-
-
Save Metapyziks/2d1104fcd0010ca07b36 to your computer and use it in GitHub Desktop.
Example game authored using the BudgetBoy API.
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
using System.Collections.Generic; | |
using GameAPI; | |
using GameAPI.BudgetBoy; | |
namespace SmashBlox.Stages | |
{ | |
class AttractStage : Stage<Main> | |
{ | |
private Demo _demo; | |
private int _frame; | |
private Sprite _insertCoin; | |
public AttractStage(Main game, Demo demo) | |
: base(game) | |
{ | |
_demo = demo; | |
_demo.IsLooping = true; | |
var text = Graphics.GetImage("insertcoin"); | |
var swatch = Graphics.Palette.FindSwatch(0xffffff, 0xffffff, 0xffffff); | |
_insertCoin = Add(new Sprite(text, swatch), 0); | |
_insertCoin.Position = (Graphics.Size - _insertCoin.Size) / 2; | |
StartCoroutine(Flashy); | |
} | |
private IEnumerator<IAwaitable> Flashy() | |
{ | |
while (true) { | |
_insertCoin.IsVisible = true; | |
yield return Delay(0.5); | |
_insertCoin.IsVisible = false; | |
yield return Delay(0.5); | |
} | |
} | |
protected override void OnUpdate() | |
{ | |
if (Controls.A.JustPressed || Controls.B.JustPressed || | |
Controls.Start.JustPressed || Controls.Select.JustPressed || | |
Controls.Horizontal.Value != 0 || Controls.Vertical.Value != 0) { | |
Game.Start(); | |
} | |
base.OnUpdate(); | |
} | |
protected override void OnRender() | |
{ | |
Graphics.Render(_demo.GetFrameStream(_frame++)); | |
base.OnRender(); | |
} | |
} | |
} |
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
using System.Linq; | |
using GameAPI.BudgetBoy; | |
namespace SmashBlox.Entities | |
{ | |
class Ball : Entity<Main> | |
{ | |
public Vector2f Velocity { get; set; } | |
private Sound _paddleHit; | |
private Sound _blockHit; | |
protected override void OnLoadAudio(Audio audio) | |
{ | |
base.OnLoadAudio(audio); | |
_paddleHit = audio.GetSound("bounce2"); | |
_blockHit = audio.GetSound("bounce"); | |
} | |
protected override void OnLoadGraphics(Graphics graphics) | |
{ | |
base.OnLoadGraphics(graphics); | |
var image = graphics.GetImage("ball"); | |
var swatch = graphics.Palette.FindSwatch(0xffffff, 0xffffff, 0xffffff); | |
AddSprite(new Sprite(image, swatch), new Vector2i(-2, -2)); | |
CalculateBounds(); | |
} | |
public void Bounce(Vector2f normal) | |
{ | |
Bounce(normal, 1f); | |
} | |
public void Bounce(Vector2f normal, float scale) | |
{ | |
float dot = Velocity.Dot(normal); | |
if (dot >= 0f) return; | |
Velocity -= (1 + scale) * normal * dot; | |
} | |
protected override void OnUpdate(double dt) | |
{ | |
base.OnUpdate(dt); | |
Position += Velocity * (float) dt; | |
if (X < 8f) { | |
X = 8f; Bounce(Vector2f.UnitX); | |
Stage.Audio.Play(_paddleHit, 1f, 1f); | |
} else if (X > Stage.Graphics.WidthPixels - 8f) { | |
X = Stage.Graphics.WidthPixels - 8f; Bounce(-Vector2f.UnitX); | |
Stage.Audio.Play(_paddleHit, 1f, 1f); | |
} | |
if (Y > Stage.Graphics.HeightPixels - 8f) { | |
Y = Stage.Graphics.HeightPixels - 8f; Bounce(-Vector2f.UnitY); | |
Stage.Audio.Play(_paddleHit, 1f, 1f); | |
} | |
var paddle = Stage.GetEntities<Paddle>().FirstOrDefault(x => x.Bounds.Intersects(Bounds)); | |
if (paddle != null) { | |
Bounce(Vector2f.UnitY); | |
//Velocity += new Vector2f(X - paddle.Bounds.Center.X, 0f) * 64 / paddle.Bounds.Width; | |
Stage.Audio.Play(_paddleHit, 1f, 1f); | |
} | |
Vector2f normal; int phase; | |
if (Stage.GetEntity<BlockGrid>().CheckForCollision(this, out normal, out phase)) { | |
if (normal.X > 0) { | |
Bounce(Vector2f.UnitX); | |
} else if (normal.X < 0) { | |
Bounce(-Vector2f.UnitX); | |
} | |
if (normal.Y > 0) { | |
Bounce(Vector2f.UnitY); | |
} else if (normal.Y < 0) { | |
Bounce(-Vector2f.UnitY); | |
} | |
Stage.Audio.Play(_blockHit, 1f, 1f - Mathf.Log(phase, 10) / 2f); | |
} | |
} | |
} | |
} |
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
using System; | |
using System.Collections.Generic; | |
using GameAPI.BudgetBoy; | |
namespace SmashBlox.Entities | |
{ | |
class BlockGrid : Entity<Main> | |
{ | |
private Tilemap _tiles; | |
private int[] _grid; | |
private Image _blockImage; | |
private Swatch[] _blockSwatches; | |
public int Phases { get { return _blockSwatches.Length; } } | |
public int Columns { get { return _tiles.Columns; } } | |
public int Rows { get { return _tiles.Rows; } } | |
public BlockGrid(int cols, int rows) | |
{ | |
_tiles = new Tilemap(new Vector2i(16, 8), new Vector2i(cols, rows)); | |
_grid = new int[cols * rows]; | |
LocalBounds = new Bounds(0, 0, _tiles.Width, _tiles.Height); | |
} | |
protected override void OnLoadGraphics(Graphics graphics) | |
{ | |
base.OnLoadGraphics(graphics); | |
_blockImage = graphics.GetImage("block"); | |
_blockSwatches = new Swatch[] { | |
graphics.Palette.FindSwatch(0x0000FC, 0x0078F8, 0x3CBCFC), | |
graphics.Palette.FindSwatch(0x940084, 0xD800CC, 0xF878F8), | |
graphics.Palette.FindSwatch(0xA81000, 0xF83800, 0xF87858), | |
graphics.Palette.FindSwatch(0x503000, 0xAC7C00, 0xF8B800), | |
graphics.Palette.FindSwatch(0x007800, 0x00B800, 0xB8F818) | |
}; | |
} | |
private bool IsColliding(Vector2f pos, out Vector2i block, ref int phase) | |
{ | |
block = (Vector2i) pos; | |
if (pos.X >= 0f && pos.X < Columns && pos.Y >= 0f && pos.Y <= Rows) { | |
var p = this[(int) pos.X, (int) pos.Y]; | |
phase = Math.Max(p, phase); | |
return p > 0; | |
} | |
return false; | |
} | |
public bool CheckForCollision(Ball ball, out Vector2f normal, out int phase) | |
{ | |
normal = Vector2f.Zero; | |
phase = 0; | |
if (!ball.Bounds.Intersects(Bounds)) return false; | |
var bounds = (ball.Bounds - Position) / new Vector2f(_tiles.TileWidth, _tiles.TileHeight); | |
var collided = new List<Vector2i>(); | |
Vector2i pos; | |
if (IsColliding(bounds.TopLeft, out pos, ref phase)) { | |
normal += new Vector2f(1f, -1f); | |
if (!collided.Contains(pos)) collided.Add(pos); | |
} | |
if (IsColliding(bounds.TopRight, out pos, ref phase)) { | |
normal += new Vector2f(-1f, -1f); | |
if (!collided.Contains(pos)) collided.Add(pos); | |
} | |
if (IsColliding(bounds.BottomLeft, out pos, ref phase)) { | |
normal += new Vector2f(1f, 1f); | |
if (!collided.Contains(pos)) collided.Add(pos); | |
} | |
if (IsColliding(bounds.BottomRight, out pos, ref phase)) { | |
normal += new Vector2f(-1f, 1f); | |
if (!collided.Contains(pos)) collided.Add(pos); | |
} | |
foreach (var tile in collided) { | |
this[tile.X, tile.Y] -= 1; | |
} | |
if (normal.LengthSquared > 0) { | |
normal = normal.Normalized; | |
return true; | |
} | |
return false; | |
} | |
public int this[int col, int row] | |
{ | |
get { return _grid[col + row * Columns]; } | |
set | |
{ | |
if (value < 0 || value > Phases) { | |
throw new ArgumentOutOfRangeException(); | |
} | |
int index = col + row * Columns; | |
if (_grid[index] == value) return; | |
_grid[index] = value; | |
if (value > 0) { | |
_tiles.SetTile(col, row, _blockImage, _blockSwatches[value - 1]); | |
} else { | |
_tiles.ClearTile(col, row); | |
} | |
} | |
} | |
protected override void OnRender(Graphics graphics) | |
{ | |
_tiles.X = Mathf.FloorToInt(X); | |
_tiles.Y = Mathf.FloorToInt(Y); | |
_tiles.Render(graphics); | |
} | |
} | |
} |
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
using System.Collections.Generic; | |
using GameAPI.BudgetBoy; | |
using SmashBlox.Entities; | |
namespace SmashBlox.Stages | |
{ | |
class GameStage : Stage<Main> | |
{ | |
private BlockGrid _blocks; | |
private Paddle _paddle; | |
private Ball _ball; | |
public GameStage(Main game) | |
: base(game) | |
{ | |
Graphics.SetClearColor(Graphics.Palette.FindClosest(0x000000)); | |
_paddle = Add(new Paddle { | |
X = Graphics.WidthPixels / 2, | |
Y = 8 | |
}, 0); | |
_ball = Add(new Ball(), 1); | |
_blocks = Add(new BlockGrid(12, 8) { | |
X = 4, | |
Y = Graphics.HeightPixels - 68 | |
}, 0); | |
for (int y = 0; y < _blocks.Rows; ++y) { | |
for (int x = 0; x < _blocks.Columns; ++x) { | |
if ((x + (y / 2) * 3 + 1) % 6 <= 1) continue; | |
_blocks[x, y] = 1 + (y % _blocks.Phases); | |
} | |
} | |
StartCoroutine(MainCoroutine); | |
} | |
private IEnumerator<IAwaitable> MainCoroutine() | |
{ | |
for (;;) { | |
_ball.Velocity = new Vector2f(0f, 0f); | |
_ball.Y = _paddle.Y + 8; | |
do { | |
_ball.X = _paddle.NextX; | |
yield return null; | |
} while (!Controls.A.JustPressed); | |
_ball.Velocity = new Vector2f(_paddle.NextX > _paddle.X ? 1f : -1f, 1.5f) * 64f; | |
while (_ball.Y > 4f) { | |
yield return null; | |
} | |
Audio.Play(Audio.GetSound("miss"), 1, 1); | |
} | |
} | |
} | |
} |
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
using GameAPI; | |
using GameAPI.BudgetBoy; | |
using ResourceLibrary; | |
using SmashBlox.Stages; | |
namespace SmashBlox | |
{ | |
public class Main : Game<Main> | |
{ | |
private Demo _demo; | |
public Main() : base(60, 200, 160) { } | |
protected override void OnSetupGameInfo(GameAPI.GameInfo info) | |
{ | |
info.AuthorName = "Facepunch"; | |
info.Title = "Smash Blox"; | |
info.Description = "Like Breakout but cheaper!"; | |
} | |
protected override void OnLoadResources(ResourceVolume volume) | |
{ | |
base.OnLoadResources(volume); | |
_demo = volume.Get<Demo>("attract"); | |
} | |
protected override void OnInitialize() | |
{ | |
base.OnInitialize(); | |
SetStage(new AttractStage(this, _demo)); | |
} | |
public void Start() | |
{ | |
SetStage(new GameStage(this)); | |
} | |
} | |
} |
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
using GameAPI; | |
using GameAPI.BudgetBoy; | |
namespace SmashBlox.Entities | |
{ | |
class Paddle : Entity<Main> | |
{ | |
private Image _end; | |
private Image _mid; | |
private Sprite _leftEndSprite; | |
private Sprite _rightEndSprite; | |
private Sprite[] _midSprites; | |
private Swatch _swatch; | |
private int _size; | |
private bool _sizeChanged; | |
private Axis _moveAxis; | |
public int Size | |
{ | |
get { return _size; } | |
set | |
{ | |
_size = value; | |
_sizeChanged = true; | |
LocalBounds = new Bounds(-Size * 4 - 2, -2, Size * 4 + 2, 2); | |
} | |
} | |
public float NextX | |
{ | |
get | |
{ | |
var dx = (float) (_moveAxis.Value * MoveSpeed * Stage.Timestep); | |
var margin = 8f + Size * 4f; | |
return Mathf.Clamp(X + dx, margin, Stage.Graphics.WidthPixels - margin); | |
} | |
} | |
public float MoveSpeed { get; set; } | |
public Paddle() | |
{ | |
Size = 4; | |
MoveSpeed = 128f; | |
} | |
private void Resize() | |
{ | |
if (_leftEndSprite == null) return; | |
_sizeChanged = false; | |
SetSpriteOffset(_leftEndSprite, new Vector2i(-Size * 4 - _leftEndSprite.Width, -2)); | |
SetSpriteOffset(_rightEndSprite, new Vector2i(Size * 4, -2)); | |
if (_midSprites != null) { | |
foreach (var sprite in _midSprites) { | |
RemoveSprite(sprite); | |
} | |
} | |
_midSprites = new Sprite[Size]; | |
for (int i = 0; i < _midSprites.Length; ++i) { | |
_midSprites[i] = AddSprite(new Sprite(_mid, _swatch), new Vector2i(-Size * 4 + i * 8, -2)); | |
} | |
} | |
protected override void OnLoadGraphics(Graphics graphics) | |
{ | |
base.OnLoadGraphics(graphics); | |
_end = graphics.GetImage("paddle", "end"); | |
_mid = graphics.GetImage("paddle", "mid"); | |
_swatch = graphics.Palette.FindSwatch(0xffffff, 0xffffff, 0xffffff); | |
_leftEndSprite = AddSprite(new Sprite(_end, _swatch)); | |
_rightEndSprite = AddSprite(new Sprite(_end, _swatch) { FlipX = true }); | |
} | |
protected override void OnEnterStage(Stage<Main> stage) | |
{ | |
base.OnEnterStage(stage); | |
_moveAxis = stage.Controls.Horizontal; | |
} | |
protected override void OnUpdate(double dt) | |
{ | |
base.OnUpdate(dt); | |
X = NextX; | |
} | |
protected override void OnRender(Graphics graphics) | |
{ | |
if (_sizeChanged) Resize(); | |
base.OnRender(graphics); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment