Skip to content

Commit 3df76c7

Browse files
committed
Add Breakout example
1 parent e41f26a commit 3df76c7

File tree

2 files changed

+392
-1
lines changed

2 files changed

+392
-1
lines changed

Examples/Breakout.cs

+390
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,390 @@
1+
using ConsoleGameEngine;
2+
using System;
3+
4+
namespace ConsoleGameEngineExamples
5+
{
6+
internal struct Block
7+
{
8+
internal int x;
9+
internal int y;
10+
internal bool alive;
11+
internal int color;
12+
13+
internal Block(int xpos, int ypos, bool a, int c)
14+
{
15+
x = xpos;
16+
y = ypos;
17+
alive = a;
18+
color = c;
19+
}
20+
}
21+
internal class Breakout : ConsoleGame
22+
{
23+
static int fieldWidth = 24;
24+
static int fieldHeight = 30;
25+
static int ballDirectionUpRight = 0;
26+
static int ballDirectionUpLeft = 1;
27+
static int ballDirectionDownRight = 2;
28+
static int ballDirectionDownLeft = 3;
29+
static int blockRows = 8;
30+
static int blockCols = 6;
31+
static int gameStateStart = 0;
32+
static int gameStatePlaying = 1;
33+
static int gameStateEnd = 2;
34+
static int startingBlockY = 2;
35+
36+
static int startingX = 8;
37+
static int startingY = 23;
38+
static int startingBallX = 12;
39+
static int startingBallY = 22;
40+
static int defaultBallWidth = 1;
41+
static int defaultBallHeight = 1;
42+
static int startingBallXVel = 1;
43+
static int startingBallYVel = 1;
44+
static int startingBallMoveDelay = 4;
45+
static int startingBallDirection = ballDirectionUpRight;
46+
static int defaultPaddleWidth = 4;
47+
static int defaultPaddleHeight = 1;
48+
static int startingTurns = 3;
49+
static int startingGameState = gameStateStart;
50+
51+
int paddlex;
52+
int paddley;
53+
int width;
54+
int height;
55+
56+
int ballx;
57+
int bally;
58+
int ballVelx;
59+
int ballVely;
60+
int ballWidth;
61+
int ballHeight;
62+
int ballDirection;
63+
int ballMoveCounter;
64+
int ballMoveDelay;
65+
Block[,] blocks;
66+
int score;
67+
int turns;
68+
int gameState;
69+
string gameOverText;
70+
71+
private static void Main(string[] args)
72+
{
73+
new Breakout().Construct(fieldWidth, fieldHeight, 16, 16, FramerateMode.MaxFps);
74+
}
75+
76+
public override void Create()
77+
{
78+
Engine.SetPalette(Palettes.Pico8);
79+
Console.Title = "Breakout";
80+
TargetFramerate = 50;
81+
blocks = new Block[blockRows, blockCols];
82+
width = defaultPaddleWidth;
83+
height = defaultPaddleHeight;
84+
gameOverText = "";
85+
int color = 8;
86+
for (int y = 0; y < blockRows; y++)
87+
{
88+
for (int x = 0; x < blockCols; x++)
89+
{
90+
blocks[y, x] = new Block(x * width, (y * height) + startingBlockY, false, color);
91+
}
92+
color++;
93+
}
94+
gameState = startingGameState;
95+
}
96+
97+
public override void Render()
98+
{
99+
Engine.ClearBuffer();
100+
101+
if (gameState == gameStateStart)
102+
{
103+
Engine.WriteText(new Point(1, 4), "Breakout", 7);
104+
Engine.WriteText(new Point(1, 8), "Press Enter to Play", 7);
105+
Engine.WriteText(new Point(1, 12), "Press Del to Exit", 7);
106+
107+
108+
}
109+
else if (gameState == gameStatePlaying)
110+
{
111+
Engine.Fill(new Point(paddlex, paddley), new Point(paddlex + width, paddley + height), 7);
112+
113+
Engine.Fill(new Point(ballx, bally), new Point(ballx + ballWidth, bally + ballHeight), 7);
114+
115+
for (int y = 0; y < blockRows; y++)
116+
{
117+
for (int x = 0; x < blockCols; x++)
118+
{
119+
if (blocks[y, x].alive)
120+
{
121+
Engine.Fill(new Point(blocks[y, x].x, blocks[y, x].y), new Point(blocks[y, x].x + width, blocks[y, x].y + height), blocks[y, x].color);
122+
}
123+
}
124+
}
125+
126+
Engine.WriteText(new Point(1, fieldHeight - 4), "Score: " + score, 7);
127+
Engine.WriteText(new Point(1, fieldHeight - 2), "Turns: " + turns, 7);
128+
}
129+
else if (gameState == gameStateEnd)
130+
{
131+
Engine.WriteText(new Point(1, 4), gameOverText, 7);
132+
Engine.WriteText(new Point(1, 8), "Final Score: " + score, 7);
133+
Engine.WriteText(new Point(1, 12), "Press Enter to Play", 7);
134+
Engine.WriteText(new Point(1, 16), "Press del to Exit", 7);
135+
}
136+
Engine.DisplayBuffer();
137+
}
138+
139+
public override void Update()
140+
{
141+
if (gameState == gameStateStart)
142+
{
143+
if (Engine.GetKeyDown(ConsoleKey.Enter))
144+
{
145+
reset();
146+
gameState = gameStatePlaying;
147+
}
148+
}
149+
if (gameState == gameStatePlaying)
150+
{
151+
// hanterar input
152+
if (Engine.GetKeyDown(ConsoleKey.RightArrow))
153+
{
154+
paddlex++;
155+
if (paddlex > (fieldWidth - width))
156+
{
157+
paddlex = fieldWidth - width;
158+
}
159+
160+
}
161+
if (Engine.GetKeyDown(ConsoleKey.LeftArrow))
162+
{
163+
paddlex--;
164+
if (paddlex < 0) paddlex = 0;
165+
}
166+
167+
// Update ball
168+
ballMoveCounter++;
169+
if (ballMoveCounter > ballMoveDelay)
170+
{
171+
if (ballDirection == ballDirectionUpLeft)
172+
{
173+
bally -= ballVely;
174+
ballx -= ballVelx;
175+
}
176+
else if (ballDirection == ballDirectionUpRight)
177+
{
178+
bally -= ballVely;
179+
ballx += ballVelx;
180+
}
181+
else if (ballDirection == ballDirectionDownLeft)
182+
{
183+
bally += ballVely;
184+
ballx -= ballVelx;
185+
}
186+
else if (ballDirection == ballDirectionDownRight)
187+
{
188+
bally += ballVely;
189+
ballx += ballVelx;
190+
}
191+
192+
// Collide top
193+
if (bally < 0)
194+
{
195+
bally = 0;
196+
if (ballDirection == ballDirectionUpLeft)
197+
ballDirection = ballDirectionDownLeft;
198+
else if (ballDirection == ballDirectionUpRight)
199+
ballDirection = ballDirectionDownRight;
200+
}
201+
202+
if (collidePaddle())
203+
{
204+
bally -= ballVely;
205+
if (ballDirection == ballDirectionDownLeft)
206+
ballDirection = ballDirectionUpLeft;
207+
else if (ballDirection == ballDirectionDownRight)
208+
ballDirection = ballDirectionUpRight;
209+
}
210+
211+
if (collideBlocks())
212+
{
213+
if (ballDirection == ballDirectionDownLeft)
214+
{
215+
ballDirection = ballDirectionUpLeft;
216+
}
217+
else if (ballDirection == ballDirectionDownRight)
218+
{
219+
ballDirection = ballDirectionUpRight;
220+
}
221+
else if (ballDirection == ballDirectionUpLeft)
222+
{
223+
ballDirection = ballDirectionDownLeft;
224+
}
225+
else if (ballDirection == ballDirectionUpRight)
226+
{
227+
ballDirection = ballDirectionDownRight;
228+
}
229+
}
230+
231+
// collide left
232+
if (ballx < 0)
233+
{
234+
ballx = 0;
235+
if (ballDirection == ballDirectionDownLeft)
236+
{
237+
ballDirection = ballDirectionDownRight;
238+
}
239+
else if (ballDirection == ballDirectionDownRight)
240+
{
241+
ballDirection = ballDirectionDownLeft;
242+
}
243+
else if (ballDirection == ballDirectionUpLeft)
244+
{
245+
ballDirection = ballDirectionUpRight;
246+
}
247+
else if (ballDirection == ballDirectionUpRight)
248+
{
249+
ballDirection = ballDirectionUpLeft;
250+
}
251+
}
252+
253+
// collide right
254+
if (ballx >= fieldWidth - ballWidth)
255+
{
256+
ballx = fieldWidth - ballWidth;
257+
if (ballDirection == ballDirectionDownLeft)
258+
{
259+
ballDirection = ballDirectionDownRight;
260+
}
261+
else if (ballDirection == ballDirectionDownRight)
262+
{
263+
ballDirection = ballDirectionDownLeft;
264+
}
265+
else if (ballDirection == ballDirectionUpLeft)
266+
{
267+
ballDirection = ballDirectionUpRight;
268+
}
269+
else if (ballDirection == ballDirectionUpRight)
270+
{
271+
ballDirection = ballDirectionUpLeft;
272+
}
273+
}
274+
275+
// Collide down
276+
if (bally > fieldHeight)
277+
{
278+
turns--;
279+
if (turns <= 0)
280+
{
281+
gameState = gameStateEnd;
282+
gameOverText = "Game Over";
283+
}
284+
bally = startingBallY;
285+
ballDirection = startingBallDirection;
286+
}
287+
288+
ballMoveCounter = 0;
289+
}
290+
}
291+
else if (gameState == gameStateEnd)
292+
{
293+
if (Engine.GetKeyDown(ConsoleKey.Enter))
294+
{
295+
gameState = gameStateStart;
296+
}
297+
}
298+
299+
}
300+
301+
private bool collidePaddle()
302+
{
303+
bool result = false;
304+
305+
if (bally >= paddley && ballx >= paddlex && ballx < (paddlex + width) && bally <= (paddley + height))
306+
{
307+
result = true;
308+
}
309+
310+
return result;
311+
}
312+
private bool collideBlocks()
313+
{
314+
bool result = false;
315+
for (int y = 0; y < blockRows; y++)
316+
{
317+
for (int x = 0; x < blockCols; x++)
318+
{
319+
if (blocks[y, x].alive)
320+
{
321+
if (bally >= blocks[y, x].y && bally <= (blocks[y, x].y + height) && ballx >= blocks[y, x].x && ballx < (blocks[y, x].x + width))
322+
{
323+
blocks[y, x].alive = false;
324+
score += 10;
325+
result = true;
326+
if (allBlocksDead())
327+
{
328+
gameState = gameStateEnd;
329+
gameOverText = "You Win!";
330+
}
331+
break;
332+
}
333+
}
334+
}
335+
if (result)
336+
{
337+
break;
338+
}
339+
}
340+
return result;
341+
}
342+
343+
private bool allBlocksDead()
344+
{
345+
bool result = true;
346+
for (int y = 0; y < blockRows; y++)
347+
{
348+
for (int x = 0; x < blockCols; x++)
349+
{
350+
if (blocks[y, x].alive)
351+
{
352+
result = false;
353+
break;
354+
}
355+
}
356+
if (!result)
357+
{
358+
break;
359+
}
360+
}
361+
return result;
362+
}
363+
364+
private void reset()
365+
{
366+
paddlex = startingX;
367+
paddley = startingY;
368+
ballx = startingBallX;
369+
bally = startingBallY;
370+
ballWidth = defaultBallWidth;
371+
ballHeight = defaultBallHeight;
372+
ballVelx = startingBallXVel;
373+
ballVely = startingBallYVel;
374+
ballMoveCounter = 0;
375+
ballMoveDelay = startingBallMoveDelay;
376+
ballDirection = startingBallDirection;
377+
gameState = startingGameState;
378+
score = 0;
379+
turns = startingTurns;
380+
381+
for (int y = 0; y < blockRows; y++)
382+
{
383+
for (int x = 0; x < blockCols; x++)
384+
{
385+
blocks[y, x].alive = true;
386+
}
387+
}
388+
}
389+
}
390+
}

0 commit comments

Comments
 (0)