Skip to content

Commit

Permalink
starship
Browse files Browse the repository at this point in the history
  • Loading branch information
jacob-i committed Jun 25, 2024
1 parent 50066c5 commit cb47af4
Show file tree
Hide file tree
Showing 2 changed files with 232 additions and 0 deletions.
131 changes: 131 additions & 0 deletions video/ai-extensions/video-85-starship/AiExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import SwiftUI

struct GlowbyScreen: View {
static let enabled = true
static let title = "Starship Lander"

@State private var landerPosition = CGPoint(x: 160, y: 20)
@State private var landerRotation = 0.0
@State private var velocityY = 0.0
@State private var score = 0
@State private var gameOver = false
@State private var gameTimer: Timer?

let gameWidth: CGFloat = 320
let gameHeight: CGFloat = 384

var body: some View {
VStack {
Spacer()
HStack {
Spacer()
ZStack {
Rectangle()
.fill(Color.black)
.frame(width: gameWidth, height: gameHeight)
.overlay(
Rectangle()
.stroke(Color.blue, lineWidth: 4)
)

Rectangle()
.fill(Color.green)
.frame(width: 96, height: 16)
.position(x: gameWidth / 2, y: gameHeight - 8)

Rectangle()
.fill(Color.white)
.frame(width: 32, height: 48)
.rotationEffect(.degrees(landerRotation))
.position(landerPosition)

Text("Score: \(score)")
.foregroundColor(.white)
.position(x: gameWidth / 2, y: 20)
}
.frame(width: gameWidth, height: gameHeight)
.clipped()

Spacer()
}

HStack {
Button(action: { move(left: true) }) {
Text("")
.font(.title)
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}

Button(action: { move(left: false) }) {
Text("")
.font(.title)
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
}
.padding()

Button(action: restartGame) {
Text("Restart")
.font(.title)
.padding()
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(10)
}

Spacer()
}
.frame(maxWidth: 360)
.onAppear(perform: startGame)
.alert(isPresented: $gameOver) {
Alert(title: Text("Game Over"), message: Text("Your score: \(score)"), dismissButton: .default(Text("OK"), action: restartGame))
}
}

func startGame() {
landerPosition = CGPoint(x: gameWidth / 2, y: 20)
landerRotation = 0
velocityY = 0
score = 0
gameOver = false

gameTimer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { _ in
updateGame()
}
}

func updateGame() {
velocityY += 0.1
landerPosition.y += velocityY

if landerPosition.y > gameHeight - 48 {
gameTimer?.invalidate()
if abs(landerPosition.x - gameWidth / 2) < 48 && abs(landerRotation) < 15 {
score += 100
} else {
gameOver = true
}
}
}

func move(left: Bool) {
if left {
landerPosition.x -= 5
landerRotation = max(landerRotation - 5, -30)
} else {
landerPosition.x += 5
landerRotation = min(landerRotation + 5, 30)
}
}

func restartGame() {
gameTimer?.invalidate()
startGame()
}
}
101 changes: 101 additions & 0 deletions video/ai-extensions/video-85-starship/starship.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Starship Lander Game</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-900 h-screen flex flex-col items-center justify-center">
<div id="game-container" class="relative w-80 h-96 bg-black border-4 border-blue-500 overflow-hidden">
<div id="lander" class="absolute w-8 h-12 bg-white transform rotate-0 transition-transform duration-100 ease-linear" style="left: 160px; top: 20px;"></div>
<div id="landing-pad" class="absolute bottom-0 w-24 h-4 bg-green-500" style="left: 112px;"></div>
</div>
<div class="mt-4 text-white text-xl">Score: <span id="score">0</span></div>
<div class="mt-2 flex space-x-4">
<button id="left-btn" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
</button>
<button id="right-btn" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
</button>
</div>
<button id="restart-btn" class="mt-4 bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
Restart
</button>

<script>
const lander = document.getElementById('lander');
const landingPad = document.getElementById('landing-pad');
const scoreElement = document.getElementById('score');
const leftBtn = document.getElementById('left-btn');
const rightBtn = document.getElementById('right-btn');
const restartBtn = document.getElementById('restart-btn');

let posX = 160;
let posY = 20;
let velocityY = 0;
let rotation = 0;
let score = 0;
let gameLoop;

function updateLanderPosition() {
lander.style.left = `${posX}px`;
lander.style.top = `${posY}px`;
lander.style.transform = `rotate(${rotation}deg)`;
}

function gameStep() {
velocityY += 0.1; // Gravity
posY += velocityY;

if (posY > 360) { // Ground level
if (posX > 112 && posX < 176 && Math.abs(rotation) < 15) {
// Successful landing
clearInterval(gameLoop);
score += 100;
scoreElement.textContent = score;
alert('Successful landing! +100 points');
} else {
// Crash
clearInterval(gameLoop);
alert('Crash! Game Over');
}
posY = 360;
}

updateLanderPosition();
}

function startGame() {
posX = 160;
posY = 20;
velocityY = 0;
rotation = 0;
updateLanderPosition();
clearInterval(gameLoop);
gameLoop = setInterval(gameStep, 50);
}

leftBtn.addEventListener('click', () => {
posX -= 5;
rotation = Math.max(rotation - 5, -30);
updateLanderPosition();
});

rightBtn.addEventListener('click', () => {
posX += 5;
rotation = Math.min(rotation + 5, 30);
updateLanderPosition();
});

restartBtn.addEventListener('click', startGame);

document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') leftBtn.click();
if (e.key === 'ArrowRight') rightBtn.click();
});

startGame();
</script>
</body>
</html>

0 comments on commit cb47af4

Please sign in to comment.