Untitled

발표자료

공수 게임 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)
	}
}