-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dfbd190
Showing
7 changed files
with
398 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.DS_Store | ||
/.build | ||
/Packages | ||
/*.xcodeproj | ||
xcuserdata/ | ||
DerivedData/ | ||
.swiftpm/config/registries.json | ||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata | ||
.netrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"configurations": [ | ||
{ | ||
"type": "lldb", | ||
"request": "launch", | ||
"name": "Debug Snake", | ||
"program": "${workspaceFolder:snake}/.build/debug/Snake", | ||
"args": [], | ||
"cwd": "${workspaceFolder:snake}", | ||
"preLaunchTask": "swift: Build Debug Snake" | ||
}, | ||
{ | ||
"type": "lldb", | ||
"request": "launch", | ||
"name": "Release Snake", | ||
"program": "${workspaceFolder:snake}/.build/release/Snake", | ||
"args": [], | ||
"cwd": "${workspaceFolder:snake}", | ||
"preLaunchTask": "swift: Build Release Snake" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"pins" : [ | ||
{ | ||
"identity" : "raylib", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/STREGAsGate/Raylib.git", | ||
"state" : { | ||
"branch" : "master", | ||
"revision" : "e7cbfd48d26f85994fecc85881b4f38ca23516a3" | ||
} | ||
} | ||
], | ||
"version" : 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// swift-tools-version: 5.6 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "Snake", | ||
dependencies: [ | ||
// Dependencies declare other packages that this package depends on. | ||
.package(url: "https://github.com/STREGAsGate/Raylib.git", branch: "master") | ||
], | ||
targets: [ | ||
// Targets are the basic building blocks of a package. A target can define a module or a test suite. | ||
// Targets can depend on other targets in this package, and on products in packages this package depends on. | ||
.executableTarget( | ||
name: "Snake", | ||
dependencies: ["Raylib"] | ||
) | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Snake | ||
|
||
A description of this package. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,324 @@ | ||
// | ||
// Snake | ||
// | ||
|
||
import Raylib | ||
|
||
class Game { | ||
// 16:9 | ||
// private let windowWidth: Int32 = 640 | ||
// private let windowHeight: Int32 = 360 | ||
|
||
// 16:10 | ||
private let windowWidth: Int32 = 640 | ||
private let windowHeight: Int32 = 400 | ||
|
||
// 21:9 | ||
// private let windowWidth: Int32 = 840 | ||
// private let windowHeight: Int32 = 360 | ||
|
||
private let fieldSquareSize: Int32 = 20 | ||
private let fieldWidth: Int32 | ||
private let fieldHeight: Int32 | ||
private let fieldRender: RenderTexture2D | ||
// private let fieldTexture: Texture2D | ||
private let fieldPositionDraw: Vector2 | ||
|
||
struct Position2D { | ||
var x: Int32, y: Int32 | ||
} | ||
|
||
struct SnakeHead { | ||
var position: Vector2 | ||
|
||
enum Movement { | ||
case up, down, left, right | ||
} | ||
|
||
var movement: Movement | ||
var previousPosition: Position2D { | ||
var position = Position2D(x: Int32(position.x), y: Int32(position.y)) | ||
switch movement { | ||
case .up: | ||
position.y += 1 | ||
case .down: | ||
position.y -= 1 | ||
case .left: | ||
position.x += 1 | ||
case .right: | ||
position.x -= 1 | ||
} | ||
return position | ||
} | ||
let speed: Float32 | ||
} | ||
|
||
private var snakeHead = SnakeHead(position: Vector2(x: 3, y: 3), movement: .right, speed: 12.5) | ||
private var snakeTail = [Position2D]() | ||
|
||
private var fruitPosition: Position2D | ||
// Position2D(x: Int32.random(in: 0...fieldWidth), y: Int32.random(in: 0...fieldHeight)) | ||
|
||
private var isPause = false | ||
|
||
init() { | ||
Raylib.setConfigFlags(.vsyncHint) | ||
Raylib.initWindow(windowWidth, windowHeight, "Snake") | ||
// Raylib.setWindowPosition(364, 364) | ||
Raylib.setExitKey(.letterQ) | ||
|
||
fieldWidth = windowWidth / fieldSquareSize | ||
fieldHeight = windowHeight / fieldSquareSize | ||
|
||
fieldRender = Raylib.loadRenderTexture( | ||
fieldWidth * fieldSquareSize, fieldHeight * fieldSquareSize) | ||
|
||
Raylib.beginTextureMode(fieldRender) | ||
Raylib.clearBackground(.lightGray) | ||
|
||
for positionX in 0..<fieldWidth { | ||
for positionY in 0..<fieldHeight { | ||
// Notebook cells. | ||
Raylib.drawRectangle( | ||
positionX * fieldSquareSize + 1, positionY * fieldSquareSize + 1, fieldSquareSize - 2, | ||
fieldSquareSize - 2, .white) | ||
|
||
// Chess board. | ||
// if (positionX + positionY) % 2 == 0 { | ||
// Raylib.drawRectangle( | ||
// positionX * fieldSquareSize, positionY * fieldSquareSize, fieldSquareSize, | ||
// fieldSquareSize, .white) | ||
// } | ||
} | ||
} | ||
|
||
Raylib.endTextureMode() | ||
|
||
// fieldTexture = fieldRender.texture | ||
fieldPositionDraw = Vector2( | ||
x: (Float(windowWidth) - Float(fieldRender.texture.width)) / 2, | ||
y: (Float(windowHeight) - Float(fieldRender.texture.height)) / 2 | ||
) | ||
|
||
fruitPosition = Position2D( | ||
x: fieldWidth - Int32(snakeHead.position.x), | ||
y: fieldHeight - Int32(snakeHead.position.y) | ||
) | ||
|
||
// MARK: TODO | ||
// snakeTail.append(Position2D(x: Int32(snakeHead.position.x), y: Int32(snakeHead.position.y))) | ||
} | ||
|
||
private func input() { | ||
// switch Raylib.getKeyPressed() { | ||
// case .up where snakeHead.movement == .right || snakeHead.movement == .right: | ||
// snakeHead.movement = .up | ||
// case .down where snakeHead.movement == .right || snakeHead.movement == .right: | ||
// snakeHead.movement = .down | ||
// case .left where snakeHead.movement == .up || snakeHead.movement == .down: | ||
// snakeHead.movement = .left | ||
// case .right where snakeHead.movement == .up || snakeHead.movement == .down: | ||
// snakeHead.movement = .right | ||
// // case .letterP: | ||
// // isPause.toggle() | ||
// // case .letterR: | ||
// // snakeHead = SnakeHead(position: Vector2(x: 3, y: 3), movement: .right, speed: 5) | ||
// // snakeTail = [Position2D(x: Int32(snakeHead.position.x), y: Int32(snakeHead.position.y))] | ||
// default: break | ||
// } | ||
|
||
if snakeHead.movement == .up || snakeHead.movement == .down { | ||
if Raylib.isKeyPressed(.left) { | ||
snakeHead.movement = .left | ||
} | ||
if Raylib.isKeyPressed(.right) { | ||
snakeHead.movement = .right | ||
} | ||
} | ||
if snakeHead.movement == .left || snakeHead.movement == .right { | ||
if Raylib.isKeyPressed(.up) { | ||
snakeHead.movement = .up | ||
} | ||
if Raylib.isKeyPressed(.down) { | ||
snakeHead.movement = .down | ||
} | ||
} | ||
|
||
if Raylib.isKeyPressed(.letterP) || Raylib.isKeyPressed(.enter) { | ||
isPause.toggle() | ||
} | ||
if Raylib.isKeyPressed(.letterR) || Raylib.isKeyPressed(.enter) { | ||
snakeHead = SnakeHead(position: Vector2(x: 3, y: 3), movement: .right, speed: 12.5) | ||
// snakeTail = [Position2D(x: Int32(snakeHead.position.x), y: Int32(snakeHead.position.y))] | ||
snakeTail.removeAll() | ||
isPause = false | ||
} | ||
} | ||
|
||
private func update(deltaTime: Float) { | ||
if isPause { return } | ||
|
||
// let x = Int32(snakeHead.position.x) | ||
// let y = Int32(snakeHead.position.y) | ||
// if x < 0 || x >= fieldWidth || y < 0 || y >= fieldHeight { | ||
// isPause = true | ||
// } | ||
|
||
if snakeHead.position.x < 0 { | ||
snakeHead.position.x += Float(fieldWidth) | ||
} else if snakeHead.position.x > Float(fieldWidth) { | ||
snakeHead.position.x -= Float(fieldWidth) | ||
} | ||
if snakeHead.position.y < 0 { | ||
snakeHead.position.y += Float(fieldHeight) | ||
} else if snakeHead.position.y > Float(fieldHeight) { | ||
snakeHead.position.y -= Float(fieldHeight) | ||
} | ||
|
||
let previousPosition = Position2D( | ||
x: Int32(snakeHead.position.x), y: Int32(snakeHead.position.y)) | ||
|
||
switch snakeHead.movement { | ||
case .up: | ||
snakeHead.position.y -= snakeHead.speed * deltaTime | ||
case .down: | ||
snakeHead.position.y += snakeHead.speed * deltaTime | ||
case .left: | ||
snakeHead.position.x -= snakeHead.speed * deltaTime | ||
case .right: | ||
snakeHead.position.x += snakeHead.speed * deltaTime | ||
} | ||
|
||
if Int32(snakeHead.position.x) != previousPosition.x | ||
|| Int32(snakeHead.position.y) != previousPosition.y | ||
{ | ||
snakeTail.append(snakeHead.previousPosition) | ||
// snakeTail.append(Position2D(x: Int32(snakeHead.position.x), y: Int32(snakeHead.position.y))) | ||
snakeTail.removeFirst() | ||
} | ||
|
||
if Int32(snakeHead.position.x) == fruitPosition.x | ||
&& Int32(snakeHead.position.y) == fruitPosition.y | ||
{ | ||
snakeTail.append(Position2D(x: Int32(snakeHead.position.x), y: Int32(snakeHead.position.y))) | ||
|
||
fruitPosition = Position2D( | ||
x: Int32.random(in: 0..<fieldWidth), | ||
y: Int32.random(in: 0..<fieldHeight) | ||
) | ||
} | ||
|
||
// for tailItem in snakeTail | ||
// where snakeTail.count > 4 && tailItem.x != snakeTail.first?.x && tailItem.y != snakeTail.first?.y | ||
// { | ||
// if Int32(snakeHead.position.x) == tailItem.x && Int32(snakeHead.position.y) == tailItem.y { | ||
// isPause = true | ||
// } | ||
// } | ||
} | ||
|
||
private func render() { | ||
// Raylib.beginTextureMode(fieldRender) | ||
// Raylib.clearBackground(.black) | ||
|
||
// // Raylib.drawTextureV(fieldTexture, Vector2(), .white) | ||
// // Raylib.drawTexture(fieldTexture, 0, 0, .blue) | ||
// Raylib.drawRectangle(1, 1, 30, 30, .white) | ||
// // Draw snake head. | ||
// Raylib.drawRectangle( | ||
// snakeHead.position.x * fieldSquareSize, snakeHead.position.y * fieldSquareSize, | ||
// fieldSquareSize, fieldSquareSize, .magenta) | ||
|
||
// Raylib.endTextureMode() | ||
|
||
Raylib.beginDrawing() | ||
Raylib.clearBackground(.white) | ||
|
||
// Raylib.drawRectangleGradientH(0, 0, windowWidth, windowHeight, .magenta, .black) | ||
// Raylib.drawCircleGradient(windowWidth / 2, windowHeight / 2, Float(windowWidth), .black, .magenta) | ||
|
||
// Raylib.drawRectangleLines( | ||
// Int32(fieldPositionDraw.x - 1), Int32(fieldPositionDraw.y - 1), | ||
// fieldWidth * fieldSquareSize + 2, | ||
// fieldHeight * fieldSquareSize + 2, .lightGray) | ||
|
||
// Draw field border. | ||
// Raylib.drawRectangleLines( | ||
// Int32(fieldPositionDraw.x - 1), Int32(fieldPositionDraw.y - 1), | ||
// fieldWidth * fieldSquareSize + 2, | ||
// fieldHeight * fieldSquareSize + 2, .lightGray) | ||
// Draw field. | ||
Raylib.drawTextureV(fieldRender.texture, fieldPositionDraw, .white) | ||
|
||
// Draw snake tail. | ||
for snakeTailItem in snakeTail { | ||
Raylib.drawRectangleRec( | ||
Rectangle( | ||
x: Float(snakeTailItem.x) * Float(fieldSquareSize) + fieldPositionDraw.x, | ||
y: Float(snakeTailItem.y) * Float(fieldSquareSize) + fieldPositionDraw.y, | ||
width: Float(fieldSquareSize), | ||
height: Float(fieldSquareSize) | ||
), .purple) | ||
} | ||
// Draw snake head. | ||
Raylib.drawRectangleRec( | ||
Rectangle( | ||
x: Float(Int32(snakeHead.position.x)) * Float(fieldSquareSize) + fieldPositionDraw.x, | ||
y: Float(Int32(snakeHead.position.y)) * Float(fieldSquareSize) + fieldPositionDraw.y, | ||
width: Float(fieldSquareSize), | ||
height: Float(fieldSquareSize) | ||
), .darkPurple) | ||
// Draw fruit. | ||
Raylib.drawRectangleRec( | ||
Rectangle( | ||
x: Float(fruitPosition.x) * Float(fieldSquareSize) + fieldPositionDraw.x, | ||
y: Float(fruitPosition.y) * Float(fieldSquareSize) + fieldPositionDraw.y, | ||
width: Float(fieldSquareSize), height: Float(fieldSquareSize) | ||
), .red) | ||
|
||
if isPause { | ||
Raylib.drawRectangleRec( | ||
Rectangle(x: 0, y: 0, width: Float(windowWidth), height: Float(windowHeight)), | ||
// Color(r: 0, g: 0, b: 0, a: 128) | ||
Color(r: 255, g: 255, b: 255, a: 128) | ||
// Color(r: 230, g: 41, b: 55, a: 128) | ||
// Color(r: 0, g: 121, b: 241, a: 128) | ||
) | ||
|
||
let text = "Pause" | ||
let fontSize: Int32 = 30 | ||
let positionDraw = Position2D( | ||
x: (windowWidth - Raylib.measureText(text, fontSize)) / 2, y: (windowHeight - fontSize) / 2) | ||
|
||
// Draw shadow. | ||
// Raylib.drawText(text, positionDraw.x + 1, positionDraw.y + 1, fontSize, .black) | ||
// Draw text. | ||
Raylib.drawText(text, positionDraw.x, positionDraw.y, fontSize, .black) | ||
} | ||
|
||
Raylib.drawFPS(8, 8) | ||
Raylib.drawText( | ||
""" | ||
Snake head: | ||
Position: \(Int32(snakeHead.position.x)), \(Int32(snakeHead.position.y)) | ||
Speed: \(snakeHead.speed) | ||
Snake tail: | ||
Count: \(snakeTail.count) | ||
""", 8, 36, 10, .black) | ||
|
||
Raylib.endDrawing() | ||
} | ||
|
||
func run() { | ||
while !Raylib.windowShouldClose { | ||
input() | ||
update(deltaTime: Raylib.getFrameTime()) | ||
render() | ||
} | ||
} | ||
|
||
deinit { | ||
Raylib.closeWindow() | ||
} | ||
} |
Oops, something went wrong.