project-rpg/main.go

174 lines
4.0 KiB
Go
Raw Permalink Normal View History

2018-01-15 21:41:59 -07:00
package main
import (
2018-01-19 07:40:48 -07:00
"fmt"
2018-01-15 23:20:34 -07:00
"image"
2018-01-19 07:40:48 -07:00
"math"
2018-01-15 23:20:34 -07:00
"os"
2018-01-16 21:54:57 -07:00
"time"
2018-01-15 23:20:34 -07:00
2018-01-19 07:40:48 -07:00
_ "image/png"
2018-01-15 22:42:11 -07:00
"github.com/faiface/pixel"
"github.com/faiface/pixel/pixelgl"
2018-01-15 22:50:18 -07:00
"golang.org/x/image/colornames"
2018-01-15 21:41:59 -07:00
)
2018-01-15 23:20:34 -07:00
func loadPicture(path string) (pixel.Picture, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
return nil, err
}
return pixel.PictureDataFromImage(img), nil
}
2018-01-15 22:42:11 -07:00
func run() {
cfg := pixelgl.WindowConfig{
2018-01-23 03:19:02 -07:00
Title: "Project RPG",
2018-01-15 22:42:11 -07:00
Bounds: pixel.R(0, 0, 1024, 768),
2018-01-15 22:50:18 -07:00
VSync: true,
2018-01-15 22:42:11 -07:00
}
win, err := pixelgl.NewWindow(cfg)
if err != nil {
panic(err)
}
spritesheet, err := loadPicture("sprites.png")
2018-01-15 23:20:34 -07:00
if err != nil {
panic(err)
}
2018-01-23 03:15:39 -07:00
//batch := pixel.NewBatch(&pixel.TrianglesData{}, spritesheet)
2018-01-15 23:20:34 -07:00
2018-01-19 07:40:48 -07:00
background, err := loadPicture("background.png")
if err != nil {
panic(err)
}
2018-01-22 10:09:33 -07:00
bg := pixel.NewSprite(background, background.Bounds())
2018-01-19 07:40:48 -07:00
//batch := pixel.NewBatch(&pixel.TrianglesData{}, spritesheet)
2018-01-22 10:09:33 -07:00
/*
When creating the sprite, you need to know big each frame is inside the spritesheet.
If you use aseprite or some other pixel art program, you can find the number of pixels
within each frame. For our sprite sheet, each frame is 96 px wide and 96 px high. So
we increment it by 96 for both x and y so that it can get the position of the frame
at the bottom right corner.
*/
var spritesFrames []pixel.Rect
2018-01-22 10:09:33 -07:00
for x := spritesheet.Bounds().Min.X; x < spritesheet.Bounds().Max.X; x += 96 {
for y := spritesheet.Bounds().Min.Y; y < spritesheet.Bounds().Max.Y; y += 96 {
2018-01-23 03:15:39 -07:00
spritesFrames = append(spritesFrames, pixel.R(x, y, x+96, y+96)) // (x, y, width, height) of frame
2018-01-16 21:33:27 -07:00
}
}
2018-01-22 10:09:33 -07:00
Sprite := pixel.NewSprite(spritesheet, spritesFrames[3])
2018-01-16 21:10:29 -07:00
2018-01-16 21:33:27 -07:00
var (
2018-01-23 03:15:39 -07:00
camPos = pixel.ZV
2018-01-22 10:09:33 -07:00
//camSpeed = 500.0
camZoom = 0.3
2018-01-19 07:40:48 -07:00
camZoomSpeed = 1.2
)
var (
frames = 0
second = time.Tick(time.Second)
)
playerX := win.Bounds().Max.X / 2
playerY := win.Bounds().Max.Y / 2
var (
playerXY = pixel.Vec{
playerX,
playerY,
}
2018-01-16 21:33:27 -07:00
)
2018-01-15 22:50:18 -07:00
2018-01-22 10:09:33 -07:00
var fps int64 = 60
2018-01-23 03:15:39 -07:00
timePerFrame := 1000000000 / fps
2018-01-22 10:09:33 -07:00
var lastTime int64 = time.Now().UnixNano()
var now int64
var dt int64
2018-01-19 07:40:48 -07:00
2018-01-22 10:09:33 -07:00
// Game Loop
2018-01-15 22:42:11 -07:00
for !win.Closed() {
2018-01-16 07:35:04 -07:00
now = time.Now().UnixNano()
2018-01-23 03:15:39 -07:00
dt += (now - lastTime)
2018-01-22 10:09:33 -07:00
lastTime = time.Now().UnixNano()
2018-01-23 03:15:39 -07:00
2018-01-22 10:09:33 -07:00
//Execute a frame.
2018-01-23 03:15:39 -07:00
if dt >= timePerFrame {
2018-01-16 07:35:04 -07:00
2018-01-22 10:09:33 -07:00
// *** Update begins *** //
playerXY = pixel.Vec{
playerX,
playerY,
}
cam := pixel.IM.Scaled(camPos, camZoom).Moved(win.Bounds().Center().Sub(camPos))
2018-01-23 03:15:39 -07:00
2018-01-22 10:09:33 -07:00
win.SetMatrix(cam)
/*
This is where Sprite and bg was originally. Creating them over and over inside
the main loop is not very good resource management. When i added my own dt, the game was
only going about 22 fps, when it should've been going 60. I moved them
out of the loop and created them up top. It fixed it and now runs faster.
the tutorial only has it in the loop with the exception that it creates it only
if you click the button to make a tree. It only created it once and added it.
*/
2018-01-23 03:15:39 -07:00
2018-01-22 10:09:33 -07:00
//mouse := cam.Unproject(win.MousePosition())
2018-01-23 03:20:29 -07:00
speed := 10.0
2018-01-23 03:15:39 -07:00
if win.Pressed(pixelgl.KeyA) { //left
2018-01-22 10:09:33 -07:00
playerX -= speed
2018-01-23 03:15:39 -07:00
Sprite.Set(spritesheet, spritesFrames[2])
2018-01-22 10:09:33 -07:00
}
2018-01-23 03:15:39 -07:00
if win.Pressed(pixelgl.KeyD) { //Right
2018-01-22 10:09:33 -07:00
playerX += speed
Sprite.Set(spritesheet, spritesFrames[1])
}
if win.Pressed(pixelgl.KeyS) { //Down
playerY -= speed
Sprite.Set(spritesheet, spritesFrames[3])
}
if win.Pressed(pixelgl.KeyW) { //up
playerY += speed
Sprite.Set(spritesheet, spritesFrames[0])
}
camPos.X = playerX
camPos.Y = playerY
camZoom *= math.Pow(camZoomSpeed, win.MouseScroll().Y)
// *** Update Ends *** //
// *** Render begin *** //
win.Clear(colornames.Forestgreen)
bg.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
Sprite.Draw(win, pixel.IM.Scaled(pixel.ZV, 4).Moved(playerXY))
2018-01-23 03:15:39 -07:00
2018-01-22 10:09:33 -07:00
//batch.Draw(win)
win.Update()
2018-01-23 03:15:39 -07:00
2018-01-22 10:09:33 -07:00
// *** Render End *** //
frames++
select {
case <-second:
win.SetTitle(fmt.Sprintf("%s | FPS: %d", cfg.Title, frames))
frames = 0
default:
}
2018-01-19 07:40:48 -07:00
}
2018-01-15 22:42:11 -07:00
}
}
2018-01-15 21:41:59 -07:00
func main() {
2018-01-15 22:42:11 -07:00
pixelgl.Run(run)
2018-01-15 21:41:59 -07:00
}