mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Move a piece
This commit is contained in:
parent
bc7dd51adf
commit
631b226b5b
@ -13,11 +13,49 @@ func NewField() *Field {
|
||||
return &Field{}
|
||||
}
|
||||
|
||||
func (f *Field) IsBlocked(x, y int) bool {
|
||||
if x < 0 || fieldBlockNumX <= x {
|
||||
return true
|
||||
}
|
||||
if y < 0 {
|
||||
return false
|
||||
}
|
||||
if fieldBlockNumX <= y {
|
||||
return true
|
||||
}
|
||||
return f.blocks[x][y] != BlockTypeNone
|
||||
}
|
||||
|
||||
func (f *Field) collides(piece *Piece, x, y int, angle Angle) bool {
|
||||
return piece.collides(f, x, y, angle)
|
||||
}
|
||||
|
||||
func (f *Field) MovePieceToLeft(piece *Piece, x, y int, angle Angle) int {
|
||||
if f.collides(piece, x-1, y, angle) {
|
||||
return x
|
||||
}
|
||||
return x - 1
|
||||
}
|
||||
|
||||
func (f *Field) MovePieceToRight(piece *Piece, x, y int, angle Angle) int {
|
||||
if f.collides(piece, x+1, y, angle) {
|
||||
return x
|
||||
}
|
||||
return x + 1
|
||||
}
|
||||
|
||||
func (f *Field) RotatePieceRight(piece *Piece, x, y int, angle Angle) Angle {
|
||||
if f.collides(piece, x, y, angle.RotateRight()) {
|
||||
return angle
|
||||
}
|
||||
return angle.RotateRight()
|
||||
}
|
||||
|
||||
func (f *Field) Draw(context graphics.Context, geo matrix.Geometry) {
|
||||
blocks := make([][]BlockType, len(f.blocks))
|
||||
for i, blockLine := range f.blocks {
|
||||
blocks[i] = make([]BlockType, len(blockLine))
|
||||
copy(blocks[i], blockLine[:])
|
||||
for i, blockCol := range f.blocks {
|
||||
blocks[i] = make([]BlockType, len(blockCol))
|
||||
copy(blocks[i], blockCol[:])
|
||||
}
|
||||
drawBlocks(context, blocks, geo)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package blocks
|
||||
import (
|
||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
||||
"github.com/hajimehoshi/go-ebiten/ui"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"time"
|
||||
@ -13,10 +14,13 @@ func init() {
|
||||
}
|
||||
|
||||
type GameScene struct {
|
||||
field *Field
|
||||
rand *rand.Rand
|
||||
currentPiece *Piece
|
||||
nextPiece *Piece
|
||||
field *Field
|
||||
rand *rand.Rand
|
||||
currentPiece *Piece
|
||||
currentPieceX int
|
||||
currentPieceY int
|
||||
currentPieceAngle Angle
|
||||
nextPiece *Piece
|
||||
}
|
||||
|
||||
func NewGameScene() *GameScene {
|
||||
@ -32,15 +36,36 @@ const fieldWidth = blockWidth * fieldBlockNumX
|
||||
const fieldHeight = blockHeight * fieldBlockNumY
|
||||
|
||||
func (s *GameScene) choosePiece() *Piece {
|
||||
// Omit BlockTypeNone.
|
||||
num := int(BlockTypeMax) - 1
|
||||
blockType := BlockType(s.rand.Intn(num) + 1)
|
||||
//num := NormalBlockTypeNum
|
||||
//blockType := BlockType(s.rand.Intn(num) + 1)
|
||||
blockType := BlockType1
|
||||
return Pieces[blockType]
|
||||
}
|
||||
|
||||
func (s *GameScene) Update(state *GameState) {
|
||||
if s.currentPiece == nil {
|
||||
s.currentPiece = s.choosePiece()
|
||||
x, y := s.currentPiece.InitialPosition()
|
||||
s.currentPieceX = x
|
||||
s.currentPieceY = y
|
||||
s.currentPieceAngle = Angle0
|
||||
}
|
||||
if state.Input.StateForKey(ui.KeySpace) == 1 {
|
||||
s.currentPieceAngle = s.field.RotatePieceRight(
|
||||
s.currentPiece, s.currentPieceX, s.currentPieceY,
|
||||
s.currentPieceAngle)
|
||||
}
|
||||
l := state.Input.StateForKey(ui.KeyLeft)
|
||||
if l == 1 || (10 <= l && l % 2 == 0) {
|
||||
s.currentPieceX = s.field.MovePieceToLeft(
|
||||
s.currentPiece, s.currentPieceX, s.currentPieceY,
|
||||
s.currentPieceAngle)
|
||||
}
|
||||
r := state.Input.StateForKey(ui.KeyRight)
|
||||
if r == 1 || (10 <= r && r % 2 == 0) {
|
||||
s.currentPieceX = s.field.MovePieceToRight(
|
||||
s.currentPiece, s.currentPieceX, s.currentPieceY,
|
||||
s.currentPieceAngle)
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,8 +74,8 @@ func (s *GameScene) Draw(context graphics.Context) {
|
||||
|
||||
field := drawInfo.textures["empty"]
|
||||
geoMat := matrix.IdentityGeometry()
|
||||
geoMat.Scale(float64(fieldWidth) / float64(emptyWidth),
|
||||
float64(fieldHeight) / float64(emptyHeight))
|
||||
geoMat.Scale(float64(fieldWidth)/float64(emptyWidth),
|
||||
float64(fieldHeight)/float64(emptyHeight))
|
||||
geoMat.Translate(20, 20) // magic number?
|
||||
colorMat := matrix.IdentityColor()
|
||||
colorMat.Scale(color.RGBA{0, 0, 0, 0x80})
|
||||
@ -61,6 +86,7 @@ func (s *GameScene) Draw(context graphics.Context) {
|
||||
s.field.Draw(context, geoMat)
|
||||
|
||||
if s.currentPiece != nil {
|
||||
s.currentPiece.Draw(context, geoMat)
|
||||
s.currentPiece.Draw(context, 20, 20,
|
||||
s.currentPieceX, s.currentPieceY, s.currentPieceAngle)
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,22 @@ func init() {
|
||||
texturePaths["blocks"] = "images/blocks/blocks.png"
|
||||
}
|
||||
|
||||
type Angle int
|
||||
|
||||
const (
|
||||
Angle0 Angle = iota
|
||||
Angle90
|
||||
Angle180
|
||||
Angle270
|
||||
)
|
||||
|
||||
func (a Angle) RotateRight() Angle {
|
||||
if a == Angle270 {
|
||||
return Angle0
|
||||
}
|
||||
return a + 1
|
||||
}
|
||||
|
||||
type BlockType int
|
||||
|
||||
const (
|
||||
@ -20,9 +36,10 @@ const (
|
||||
BlockType5
|
||||
BlockType6
|
||||
BlockType7
|
||||
BlockTypeMax
|
||||
)
|
||||
|
||||
const NormalBlockTypeNum = 7
|
||||
|
||||
type Piece struct {
|
||||
blockType BlockType
|
||||
blocks [][]bool
|
||||
@ -30,67 +47,70 @@ type Piece struct {
|
||||
|
||||
func toBlocks(ints [][]int) [][]bool {
|
||||
blocks := make([][]bool, len(ints))
|
||||
for i, line := range ints {
|
||||
blocks[i] = make([]bool, len(line))
|
||||
for j, v := range line {
|
||||
blocks[i][j] = v != 0
|
||||
for j, row := range ints {
|
||||
blocks[j] = make([]bool, len(row))
|
||||
}
|
||||
// Tranpose the argument matrix.
|
||||
for i, col := range ints {
|
||||
for j, v := range col {
|
||||
blocks[j][i] = v != 0
|
||||
}
|
||||
}
|
||||
return blocks
|
||||
}
|
||||
|
||||
var Pieces = map[BlockType]*Piece{
|
||||
BlockTypeNone: nil,
|
||||
BlockType1: &Piece{
|
||||
blockType: BlockType1,
|
||||
blocks: toBlocks([][]int{
|
||||
{0, 1, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{1, 1, 1, 1},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
}),
|
||||
},
|
||||
BlockType2: &Piece{
|
||||
blockType: BlockType2,
|
||||
blocks: toBlocks([][]int{
|
||||
{0, 1, 1},
|
||||
{0, 1, 0},
|
||||
{0, 1, 0},
|
||||
{1, 0, 0},
|
||||
{1, 1, 1},
|
||||
{0, 0, 0},
|
||||
}),
|
||||
},
|
||||
BlockType3: &Piece{
|
||||
blockType: BlockType3,
|
||||
blocks: toBlocks([][]int{
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{0, 1, 0},
|
||||
{1, 1, 1},
|
||||
{0, 0, 0},
|
||||
}),
|
||||
},
|
||||
BlockType4: &Piece{
|
||||
blockType: BlockType4,
|
||||
blocks: toBlocks([][]int{
|
||||
{0, 1, 0},
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{0, 0, 1},
|
||||
{1, 1, 1},
|
||||
{0, 0, 0},
|
||||
}),
|
||||
},
|
||||
BlockType5: &Piece{
|
||||
blockType: BlockType5,
|
||||
blocks: toBlocks([][]int{
|
||||
{0, 0, 1},
|
||||
{1, 1, 0},
|
||||
{0, 1, 1},
|
||||
{0, 1, 0},
|
||||
{0, 0, 0},
|
||||
}),
|
||||
},
|
||||
BlockType6: &Piece{
|
||||
blockType: BlockType6,
|
||||
blocks: toBlocks([][]int{
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{0, 0, 1},
|
||||
{1, 1, 0},
|
||||
{0, 0, 0},
|
||||
}),
|
||||
},
|
||||
BlockType7: &Piece{
|
||||
blockType: BlockType7,
|
||||
blocks: toBlocks([][]int{
|
||||
{1, 1},
|
||||
{1, 1},
|
||||
@ -105,13 +125,13 @@ const fieldBlockNumY = 20
|
||||
|
||||
func drawBlocks(context graphics.Context, blocks [][]BlockType, geo matrix.Geometry) {
|
||||
parts := []graphics.TexturePart{}
|
||||
for i, blockLine := range blocks {
|
||||
for j, block := range blockLine {
|
||||
for i, blockCol := range blocks {
|
||||
for j, block := range blockCol {
|
||||
if block == BlockTypeNone {
|
||||
continue
|
||||
}
|
||||
locationX := j * blockWidth
|
||||
locationY := i * blockHeight
|
||||
locationX := i * blockWidth
|
||||
locationY := j * blockHeight
|
||||
source := graphics.Rect{
|
||||
(int(block) - 1) * blockWidth, 0,
|
||||
blockWidth, blockHeight}
|
||||
@ -127,15 +147,68 @@ func drawBlocks(context graphics.Context, blocks [][]BlockType, geo matrix.Geome
|
||||
context.DrawTextureParts(blocksTexture, parts, geo, matrix.IdentityColor())
|
||||
}
|
||||
|
||||
func (p *Piece) Draw(context graphics.Context, geo matrix.Geometry) {
|
||||
blocks := make([][]BlockType, len(p.blocks))
|
||||
for i, blockLine := range p.blocks {
|
||||
blocks[i] = make([]BlockType, len(blockLine))
|
||||
for j, v := range blockLine {
|
||||
if v {
|
||||
func (p *Piece) InitialPosition() (int, int) {
|
||||
size := len(p.blocks)
|
||||
x := (fieldBlockNumX - size) / 2
|
||||
y := 0
|
||||
Loop:
|
||||
for j := 0; j < size; j++ {
|
||||
for i := 0; i < size; i++ {
|
||||
if p.blocks[i][j] {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
y--
|
||||
}
|
||||
return x, y
|
||||
}
|
||||
|
||||
func (p *Piece) isBlocked(i, j int, angle Angle) bool {
|
||||
size := len(p.blocks)
|
||||
i2, j2 := i, j
|
||||
switch angle {
|
||||
case Angle0:
|
||||
case Angle90:
|
||||
i2 = j
|
||||
j2 = size-1-i
|
||||
case Angle180:
|
||||
i2 = size-1-i
|
||||
j2 = size-1-j
|
||||
case Angle270:
|
||||
i2 = size-1-j
|
||||
j2 = i
|
||||
}
|
||||
return p.blocks[i2][j2]
|
||||
}
|
||||
|
||||
func (p *Piece) collides(field *Field, x, y int, angle Angle) bool {
|
||||
size := len(p.blocks)
|
||||
for i := 0; i < size; i++ {
|
||||
for j := 0; j < size; j++ {
|
||||
if field.IsBlocked(x+i, y+j) && p.isBlocked(i, j, angle) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Piece) Draw(context graphics.Context, fieldX, fieldY int, pieceX, pieceY int, angle Angle) {
|
||||
size := len(p.blocks)
|
||||
blocks := make([][]BlockType, size)
|
||||
for i, _ := range p.blocks {
|
||||
blocks[i] = make([]BlockType, size)
|
||||
for j, _ := range blocks[i] {
|
||||
if p.isBlocked(i, j, angle) {
|
||||
blocks[i][j] = p.blockType
|
||||
}
|
||||
}
|
||||
}
|
||||
drawBlocks(context, blocks, geo)
|
||||
|
||||
geoMat := matrix.IdentityGeometry()
|
||||
x := fieldX + pieceX * blockWidth
|
||||
y := fieldY + pieceY * blockHeight
|
||||
geoMat.Translate(float64(x), float64(y))
|
||||
|
||||
drawBlocks(context, blocks, geoMat)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user