
발표자료
공수 게임 4조.pptx
game.zip
main.go
package main
import (
"fmt"
"image"
_ "image/jpeg"
_ "image/png"
"log"
"math"
"os"
"github.com/hajimehoshi/ebiten/v2"
)
const (
screenWidth = 960
screenHeight = 540
)
type Game struct {
background1 *ebiten.Image // 배경
background2 *ebiten.Image // 왼쪽 RED
background3 *ebiten.Image // 오른쪽 BLUE
background4 *ebiten.Image // WALL
background5 *ebiten.Image // RED P
background6 *ebiten.Image // BLUE P
background7 *ebiten.Image // RED WIN
background8 *ebiten.Image // BLUE WIN
background9 *ebiten.Image // RED POTAN
background10 *ebiten.Image // BLUE POTAN
background11 *ebiten.Image // RED PO
background12 *ebiten.Image // BLUE PO
background2Path string
background3Path string
background4Path string
background5Path string
background6Path string
background9Path string
background10Path string
x2, y2 float64
x3, y3 float64
x4, y4 float64
x5, y5 float64
x6, y6 float64
x7, y7 float64
x8, y8 float64
x9, y9 float64
x10, y10 float64
x11, y11 float64
x12, y12 float64
background2Width int
background2Height int
background3Width int
background3Height int
background4Width int
background4Height int
background5Width int
background5Height int
background6Width int
background6Height int
background9Width int
background9Height int
background10Width int
background10Height int
angleblue float64
anglered float64
angleswichred int
angleswichblue int
cooltimered float64
cooltimeblue float64
speedx9 float64
speedy9 float64
speedx10 float64
speedy10 float64
gravity float64
air_res float64
redp int
bluep int
Gameover int
}
func NewGame() (*Game, error) {
game := &Game{
x2: 660, y2: 320,
x3: 220, y3: 320,
x4: 460, y4: 330,
x5: 575, y5: 0,
x6: 85, y6: 0,
x7: 220, y7: 1880,
x8: 220, y8: 1880,
x9: 220, y9: 1880,
x10: 220, y10: 1880,
x11: 630, y11: 365,
x12: 255, y12: 375,
background2Path: "images/red_tank_p5.png",
background2Width: 100,
background2Height: 200,
background3Path: "images/blue_tank_p5.png",
background3Width: 100,
background3Height: 200,
background4Path: "images/wall.png",
background4Width: 50,
background4Height: 150,
background5Path: "images/red_p5.png",
background5Width: 300,
background5Height: 100,
background6Path: "images/blue_p5.png",
background6Width: 300,
background6Height: 100,
background9Path: "images/potan.png",
background9Width: 10,
background9Height: 10,
background10Path: "images/potan.png",
background10Width: 10,
background10Height: 10,
angleswichred: 1,
angleswichblue: 0,
cooltimered: 0,
cooltimeblue: 0,
speedx9: 0,
speedy9: 0,
speedx10: 0,
speedy10: 0,
gravity: 0.1,
air_res: 0.001,
redp: 5,
bluep: 5,
Gameover: 0,
}
f1, err := os.Open("images/background.jpg")
if err != nil {
return nil, fmt.Errorf("failed to open image 1: %w", err)
}
defer f1.Close()
img1, _, err := image.Decode(f1)
if err != nil {
return nil, fmt.Errorf("failed to decode image 1: %w", err)
}
game.background1 = resizeImage(img1, 960, 540)
if err := game.loadBackground2(); err != nil {
return nil, err
}
if err := game.loadBackground3(); err != nil {
return nil, err
}
if err := game.loadBackground4(); err != nil {
return nil, err
}
if err := game.loadBackground5(); err != nil {
return nil, err
}
if err := game.loadBackground6(); err != nil {
return nil, err
}
f7, err := os.Open("images/red_win.png")
if err != nil {
return nil, fmt.Errorf("failed to open image 7: %w", err)
}
defer f7.Close()
img7, _, err := image.Decode(f7)
if err != nil {
return nil, fmt.Errorf("failed to decode image 7: %w", err)
}
game.background7 = resizeImage(img7, 500, 500)
f8, err := os.Open("images/blue_win.png")
if err != nil {
return nil, fmt.Errorf("failed to open image 8: %w", err)
}
defer f8.Close()
img8, _, err := image.Decode(f8)
if err != nil {
return nil, fmt.Errorf("failed to decode image 8: %w", err)
}
game.background8 = resizeImage(img8, 500, 500)
if err := game.loadBackground9(); err != nil {
return nil, err
}
if err := game.loadBackground10(); err != nil {
return nil, err
}
f11, err := os.Open("images/red_po.png")
if err != nil {
return nil, fmt.Errorf("failed to open image 11: %w", err)
}
defer f11.Close()
img11, _, err := image.Decode(f11)
if err != nil {
return nil, fmt.Errorf("failed to decode image 11: %w", err)
}
game.background11 = resizeImage(img11, 100, 50)
f12, err := os.Open("images/blue_po.png")
if err != nil {
return nil, fmt.Errorf("failed to open image 12: %w", err)
}
defer f12.Close()
img12, _, err := image.Decode(f12)
if err != nil {
return nil, fmt.Errorf("failed to decode image 12: %w", err)
}
game.background12 = resizeImage(img12, 80, 30)
return game, nil
}
func (g *Game) loadBackground2() error {
f2, err := os.Open(g.background2Path)
if err != nil {
return fmt.Errorf("failed to open image 2: %w", err)
}
defer f2.Close()
img2, _, err := image.Decode(f2)
if err != nil {
return fmt.Errorf("failed to decode image 2: %w", err)
}
g.background2 = resizeImage(img2, g.background2Width, g.background2Height)
return nil
}
func (g *Game) loadBackground3() error {
f3, err := os.Open(g.background3Path)
if err != nil {
return fmt.Errorf("failed to open image 3: %w", err)
}
defer f3.Close()
img3, _, err := image.Decode(f3)
if err != nil {
return fmt.Errorf("failed to decode image 3: %w", err)
}
g.background3 = resizeImage(img3, g.background3Width, g.background3Height)
return nil
}
func (g *Game) loadBackground4() error {
f4, err := os.Open(g.background4Path)
if err != nil {
return fmt.Errorf("failed to open image 4: %w", err)
}
defer f4.Close()
img4, _, err := image.Decode(f4)
if err != nil {
return fmt.Errorf("failed to decode image 4: %w", err)
}
g.background4 = resizeImage(img4, g.background4Width, g.background4Height)
return nil
}
func (g *Game) loadBackground5() error {
f5, err := os.Open(g.background5Path)
if err != nil {
return fmt.Errorf("failed to open image 5: %w", err)
}
defer f5.Close()
img5, _, err := image.Decode(f5)
if err != nil {
return fmt.Errorf("failed to decode image 5: %w", err)
}
g.background5 = resizeImage(img5, g.background5Width, g.background5Height)
return nil
}
func (g *Game) loadBackground6() error {
f6, err := os.Open(g.background6Path)
if err != nil {
return fmt.Errorf("failed to open image 6: %w", err)
}
defer f6.Close()
img6, _, err := image.Decode(f6)
if err != nil {
return fmt.Errorf("failed to decode image 6: %w", err)
}
g.background6 = resizeImage(img6, g.background6Width, g.background6Height)
return nil
}
func (g *Game) loadBackground9() error {
f9, err := os.Open(g.background9Path)
if err != nil {
return fmt.Errorf("failed to open image 9: %w", err)
}
defer f9.Close()
img9, _, err := image.Decode(f9)
if err != nil {
return fmt.Errorf("failed to decode image 9: %w", err)
}
g.background9 = resizeImage(img9, g.background9Width, g.background9Height)
return nil
}
func (g *Game) loadBackground10() error {
f10, err := os.Open(g.background10Path)
if err != nil {
return fmt.Errorf("failed to open image 10: %w", err)
}
defer f10.Close()
img10, _, err := image.Decode(f10)
if err != nil {
return fmt.Errorf("failed to decode image 10: %w", err)
}
g.background10 = resizeImage(img10, g.background10Width, g.background10Height)
return nil
}
func resizeImage(img image.Image, width, height int) *ebiten.Image {
originalBounds := img.Bounds()
originalWidth := originalBounds.Dx()
originalHeight := originalBounds.Dy()
if originalWidth == width && originalHeight == height {
return ebiten.NewImageFromImage(img)
}
resizedImg := image.NewRGBA(image.Rect(0, 0, width, height))
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
xp := x * originalWidth / width
yp := y * originalHeight / height
resizedImg.Set(x, y, img.At(xp, yp))
}
}
return ebiten.NewImageFromImage(resizedImg)
}
func (g *Game) Update() error {
if g.Gameover == 0 {
if ebiten.IsKeyPressed(ebiten.KeyU) {
g.background9Path = "images/potan2.png"
g.background10Path = "images/potan2.png"
if err := g.loadBackground9(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground10(); err != nil {
log.Fatal(err)
}
}
if ebiten.IsKeyPressed(ebiten.KeyI) {
g.background9Path = "images/potan.png"
g.background10Path = "images/potan.png"
if err := g.loadBackground9(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground10(); err != nil {
log.Fatal(err)
}
}
if g.x2 < 880 {
if ebiten.IsKeyPressed(ebiten.KeyArrowRight) {
g.x2 += 2
g.x11 += 2
}
}
if g.x2 > 490 {
if ebiten.IsKeyPressed(ebiten.KeyArrowLeft) {
g.x2 -= 2
g.x11 -= 2
}
}
if g.x3 < 390 {
if ebiten.IsKeyPressed(ebiten.KeyD) {
g.x3 += 2
g.x12 += 2
}
}
if g.x3 > 0 {
if ebiten.IsKeyPressed(ebiten.KeyA) {
g.x3 -= 2
g.x12 -= 2
}
}
if g.redp == 5 {
g.background2Path = "images/red_tank_p5.png"
g.background5Path = "images/red_p5.png"
if err := g.loadBackground2(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground5(); err != nil {
log.Fatal(err)
}
}
if g.redp == 4 {
g.background2Path = "images/red_tank_p4.png"
g.background5Path = "images/red_p4.png"
if err := g.loadBackground2(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground5(); err != nil {
log.Fatal(err)
}
}
if g.redp == 3 {
g.background2Path = "images/red_tank_p3.png"
g.background5Path = "images/red_p3.png"
if err := g.loadBackground2(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground5(); err != nil {
log.Fatal(err)
}
}
if g.redp == 2 {
g.background2Path = "images/red_tank_p2.png"
g.background5Path = "images/red_p2.png"
if err := g.loadBackground2(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground5(); err != nil {
log.Fatal(err)
}
}
if g.redp == 1 {
g.background2Path = "images/red_tank_p1.png"
g.background5Path = "images/red_p1.png"
if err := g.loadBackground2(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground5(); err != nil {
log.Fatal(err)
}
}
if g.redp == 0 {
g.background2Path = "images/red_tank_p0.png"
g.background5Path = "images/p0.png"
if err := g.loadBackground2(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground5(); err != nil {
log.Fatal(err)
}
g.y8 = 0
g.Gameover = 1
}
if g.bluep == 5 {
g.background3Path = "images/blue_tank_p5.png"
g.background6Path = "images/blue_p5.png"
if err := g.loadBackground3(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground6(); err != nil {
log.Fatal(err)
}
}
if g.bluep == 4 {
g.background3Path = "images/blue_tank_p4.png"
g.background6Path = "images/blue_p4.png"
if err := g.loadBackground3(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground6(); err != nil {
log.Fatal(err)
}
}
if g.bluep == 3 {
g.background3Path = "images/blue_tank_p3.png"
g.background6Path = "images/blue_p3.png"
if err := g.loadBackground3(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground6(); err != nil {
log.Fatal(err)
}
}
if g.bluep == 2 {
g.background3Path = "images/blue_tank_p2.png"
g.background6Path = "images/blue_p2.png"
if err := g.loadBackground3(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground6(); err != nil {
log.Fatal(err)
}
}
if g.bluep == 1 {
g.background3Path = "images/blue_tank_p1.png"
g.background6Path = "images/blue_p1.png"
if err := g.loadBackground3(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground6(); err != nil {
log.Fatal(err)
}
}
if g.bluep == 0 {
g.background3Path = "images/blue_tank_p0.png"
g.background6Path = "images/p0.png"
if err := g.loadBackground3(); err != nil {
log.Fatal(err)
}
if err := g.loadBackground6(); err != nil {
log.Fatal(err)
}
g.y7 = 0
g.Gameover = 1
}
g.x9 -= g.speedx9
g.y9 -= g.speedy9
g.speedy9 -= g.gravity - g.air_res
g.cooltimered -= 1
if g.cooltimered < 0 {
if ebiten.IsKeyPressed(ebiten.KeyEnter) {
g.x9 = g.x11 + 70
g.y9 = g.y11 + 22
g.cooltimered = 180
g.speedx9 = 10 - g.anglered/9
g.speedy9 = 10 - g.speedx9
}
}
g.x10 += g.speedx10
g.y10 -= g.speedy10
g.speedy10 -= g.gravity - g.air_res
g.cooltimeblue -= 1
if g.cooltimeblue < 0 {
if ebiten.IsKeyPressed(ebiten.KeyG) {
g.x10 = g.x12 + 13
g.y10 = g.y12 + 7
g.cooltimeblue = 180
g.speedx10 = 10 + g.angleblue/9
g.speedy10 = 10 - g.speedx10
}
}
if g.angleswichred == 1 {
g.anglered += 1
if g.anglered > 90 {
g.angleswichred = 0
}
}
if g.angleswichred == 0 {
g.anglered -= 1
if g.anglered < 0 {
g.angleswichred = 1
}
}
if g.angleswichblue == 1 {
g.angleblue += 1
if g.angleblue > 0 {
g.angleswichblue = 0
}
}
if g.angleswichblue == 0 {
g.angleblue -= 1
if g.angleblue < -90 {
g.angleswichblue = 1
}
}
// 충돌 체크
if g.isCollision210() {
g.y10 = 1000
g.redp -= 1
}
if g.isCollision39() {
g.y9 = 1000
g.bluep -= 1
}
if g.isCollision49() {
g.y9 = 1000
}
if g.isCollision410() {
g.y10 = 1000
}
}
return nil
}
func (g *Game) isCollision210() bool {
bounds2 := image.Rect(int(g.x2)+5, int(g.y2)+55, int(g.x2)+95, int(g.y2)+145)
bounds10 := image.Rect(int(g.x10)+1, int(g.y10)+1, int(g.x10)+4, int(g.y10)+4)
return bounds2.Overlaps(bounds10)
}
func (g *Game) isCollision39() bool {
bounds3 := image.Rect(int(g.x3)+5, int(g.y3)+55, int(g.x3)+95, int(g.y3)+145)
bounds9 := image.Rect(int(g.x9)+1, int(g.y9)+1, int(g.x9)+4, int(g.y9)+4)
return bounds3.Overlaps(bounds9)
}
func (g *Game) isCollision49() bool {
bounds4 := image.Rect(int(g.x4)+10, int(g.y4)+5, int(g.x4)+40, int(g.y4)+145)
bounds9 := image.Rect(int(g.x9)+1, int(g.y9)+1, int(g.x9)+4, int(g.y9)+4)
return bounds4.Overlaps(bounds9)
}
func (g *Game) isCollision410() bool {
bounds4 := image.Rect(int(g.x4)+10, int(g.y4)+5, int(g.x4)+40, int(g.y4)+145)
bounds10 := image.Rect(int(g.x10)+1, int(g.y10)+1, int(g.x10)+4, int(g.y10)+4)
return bounds4.Overlaps(bounds10)
}
func (g *Game) Draw(screen *ebiten.Image) {
screen.DrawImage(g.background1, nil)
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x2, g.y2)
screen.DrawImage(g.background2, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x3, g.y3)
screen.DrawImage(g.background3, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x4, g.y4)
screen.DrawImage(g.background4, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x5, g.y5)
screen.DrawImage(g.background5, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x6, g.y6)
screen.DrawImage(g.background6, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x9, g.y9)
screen.DrawImage(g.background9, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x10, g.y10)
screen.DrawImage(g.background10, op)
op = &ebiten.DrawImageOptions{}
// 이미지의 중심을 회전 중심으로 설정하여 회전
w, h := g.background11.Size()
op.GeoM.Translate(-float64(w)/1.3, -float64(h)/2) // 중심으로 이동
op.GeoM.Rotate(g.anglered * (math.Pi / 180.0)) // 회전
op.GeoM.Translate(float64(w)/1.3, float64(h)/2) // 원래 위치로 이동
op.GeoM.Translate(g.x11, g.y11)
screen.DrawImage(g.background11, op)
op = &ebiten.DrawImageOptions{}
p, o := g.background12.Size()
op.GeoM.Translate(-float64(p)/5, -float64(o)/2)
op.GeoM.Rotate(g.angleblue * (math.Pi / 180.0))
op.GeoM.Translate(float64(p)/5, float64(o)/2)
op.GeoM.Translate(g.x12, g.y12)
screen.DrawImage(g.background12, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x7, g.y7)
screen.DrawImage(g.background7, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.x8, g.y8)
screen.DrawImage(g.background8, op)
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
// 게임 인스턴스 생성
game, err := NewGame()
if err != nil {
log.Fatal(err)
}
// 윈도우 생성
ebiten.SetWindowSize(screenWidth, screenHeight)
ebiten.SetWindowTitle("Multiple Images Example")
// 게임 실행
if err := ebiten.RunGame(game); err != nil {
log.Fatal(err)
}
}