ZIP poniżej
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <avr/pgmspace.h>
#include "level.h"
#include <stdint.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define i2c_Address 0x3C
Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
display.begin(i2c_Address, true);
display.clearDisplay();
display.setRotation(2);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(13, OUTPUT);
}
int x=15, y=30, hy=28;
int vx = 0, vxTemp = 0;
int vy = 0;
int yDash = 0;
int levelNum = 0;
int deathCount = 0;
float time = 0;
int xDtemp1, yDtemp1, xDtemp2, yDtemp2, tDash;
bool onGround = false , ableToDash = true, ableToRun = true, ableToJump = false;
bool up, down, left, right, jump, dash, tempJump;
bool onWallLeft = false;
bool onWallRight = false;
const uint8_t* levels[] = {
level0,
level1,
level2,
level3,
level4
};
const uint8_t *level = levels[0];
uint8_t getTile(int x, int y) {
if (x < 0 || y < 0 || x >= WIDTH || y >= HEIGHT) return 1;
int index = y * WIDTH + x;
int byteIndex = index / 4;
int shift = (index % 4) * 2;
uint8_t data = pgm_read_byte(&level[byteIndex]);
return (data >> shift) & 0b11;
}
void levelStart(int num){
int startPointX[]={15,5,5,5,5};
int startPointY[]={30,20,25,7,27};
x = startPointX[num];
y = startPointY[num];
hy = y-2;
level = levels[num];
tDash = 0;
xDtemp1 = 0;
yDtemp1 = 0;
xDtemp2 = 0;
yDtemp2 = 0;
}
void readInput() {
up = !digitalRead(7);
right = !digitalRead(8);
down = !digitalRead(9);
left = !digitalRead(10);
jump = !digitalRead(5);
dash = !digitalRead(4);
//game reset
if(up&&down&&right&&left&&dash&&jump){
deathCount = 0;
time = 0;
levelNum = 0;
levelStart(levelNum);
}
if(up&&down&&right&&left){
//level reset
levelStart(levelNum);
}
}
void movement() {
yDash = 0;
bool jumpPressed = jump && !tempJump;
// normalny ruch
if (vy <= 1) ableToRun = true;
if (ableToRun){
vx = 0;
if (right) vx = 1;
if (left) vx = -1;
}
// skok z ziemi
if (ableToJump) {
vy = 10;
ableToJump = false;
}
// WALL JUMP
if (!onGround && jumpPressed) {
if (onWallLeft) {
vx = 1;
vy = 10;
ableToRun = false;
}
if (onWallRight) {
vx = -1;
vy = 10;
ableToRun = false;
}
}
if (getTile(x+vx, y)!=1&&getTile(x+vx, hy)!=1) x += vx;
if (vy>1){
if (jump&&tempJump){
if (getTile(x, y-1)!=1&&getTile(x, hy-1)!=1){
y -= 1;
hy -= 1;
}else vy -= 10;
}else
if (!jump) vy = 1;
}
if (vy<0){
y += 1;
hy += 1;
vy = -1;
}
tempJump = jump;
if (dash && ableToDash){
xDtemp1 = x; yDtemp1 = y;
if(up) yDash = -1;
if(down) yDash = 1;
for (int d = 0; d < 12; d++){
if(getTile(x+vx, y+yDash)!=1&&getTile(x+vx, hy+yDash)!=1){
x = x + vx;
y = y + yDash;
hy = hy + yDash;
}
xDtemp2 = x; yDtemp2 = y;
tDash = 5;
checkHitbox();
}
ableToDash = false;
}
}
void drawTimer() {
long total = (long)(time * 100); // setne sekundy
int minutes = total / 6000;
int seconds = (total / 100) % 60;
int centiseconds = total % 100;
if(levelNum<4){
display.fillRect(0, 0, 50, 10, SH110X_BLACK);
display.setTextSize(1);
display.setCursor(0, 0);
}else{
display.setTextSize(2);
display.setCursor(14, 10);
}
display.setTextColor(SH110X_WHITE);
if (minutes < 10) display.print("0");
display.print(minutes);
display.print(":");
if (seconds < 10) display.print("0");
display.print(seconds);
display.print(".");
if (centiseconds < 10) display.print("0");
display.print(centiseconds);
}
void drawPlayer(){
//draw player
if(x%3==0||!onGround){
display.drawPixel(2*x, 2*y, SH110X_WHITE);
display.drawPixel(2*x, 2*y-1, SH110X_WHITE);
display.drawPixel(2*x+1, 2*y+1, SH110X_WHITE);
display.drawPixel(2*x-1, 2*y+1, SH110X_WHITE);
display.drawPixel(2*x+1, 2*y, SH110X_WHITE);
display.drawPixel(2*x-1, 2*y, SH110X_WHITE);
display.drawPixel(2*x+1, 2*y-2, SH110X_WHITE);
display.drawPixel(2*x-1, 2*y-2, SH110X_WHITE);
display.drawPixel(2*x+1, 2*y-3, SH110X_WHITE);
display.drawPixel(2*x-1, 2*y-3, SH110X_WHITE);
display.drawPixel(2*x, 2*y-1, SH110X_WHITE);
display.drawPixel(2*x, 2*y-2, SH110X_WHITE);
display.drawPixel(2*x, 2*y-3, SH110X_WHITE);
display.drawPixel(2*x, 2*y-4, SH110X_WHITE);
}else{
display.drawPixel(2*x, 2*y+1, SH110X_WHITE);
display.drawPixel(2*x, 2*y, SH110X_WHITE);
display.drawPixel(2*x+1, 2*y-2, SH110X_WHITE);
display.drawPixel(2*x-1, 2*y-2, SH110X_WHITE);
display.drawPixel(2*x+1, 2*y-3, SH110X_WHITE);
display.drawPixel(2*x-1, 2*y-3, SH110X_WHITE);
display.drawPixel(2*x, 2*y-1, SH110X_WHITE);
display.drawPixel(2*x, 2*y-2, SH110X_WHITE);
display.drawPixel(2*x, 2*y-3, SH110X_WHITE);
display.drawPixel(2*x, 2*y-4, SH110X_WHITE);
}
}
void drawSkull() {
int ox = 40; // offset X
int oy = 27; // offset Y
//write death count
display.setTextSize(2);
display.setCursor(ox+22, oy);
display.setTextColor(SH110X_WHITE);
display.print(deathCount);
// --- ZARYS
display.drawLine(ox+4, oy+10, ox+11, oy+10, SH110X_WHITE);
display.drawLine(ox+1, oy+8, ox+3, oy+8, SH110X_WHITE);
display.drawLine(ox+12, oy+8, ox+14, oy+8, SH110X_WHITE);
display.drawLine(ox+0, oy+4, ox+0, oy+7, SH110X_WHITE);
display.drawLine(ox+15, oy+4, ox+15, oy+7, SH110X_WHITE);
display.drawLine(ox+5, oy+0, ox+10, oy+0, SH110X_WHITE);
display.drawPixel(ox+1, oy+3, SH110X_WHITE);
display.drawPixel(ox+2, oy+2, SH110X_WHITE);
display.drawPixel(ox+3, oy+1, SH110X_WHITE);
display.drawPixel(ox+4, oy+1, SH110X_WHITE);
display.drawPixel(ox+11, oy+1, SH110X_WHITE);
display.drawPixel(ox+12, oy+1, SH110X_WHITE);
display.drawPixel(ox+13, oy+2, SH110X_WHITE);
display.drawPixel(ox+14, oy+3, SH110X_WHITE);
// --- OCZY (+)
// lewe
display.drawPixel(ox+4, oy+4, SH110X_WHITE);
display.drawPixel(ox+3, oy+5, SH110X_WHITE);
display.drawPixel(ox+4, oy+5, SH110X_WHITE);
display.drawPixel(ox+5, oy+5, SH110X_WHITE);
display.drawPixel(ox+4, oy+6, SH110X_WHITE);
// prawe
display.drawPixel(ox+11, oy+4, SH110X_WHITE);
display.drawPixel(ox+10, oy+5, SH110X_WHITE);
display.drawPixel(ox+11, oy+5, SH110X_WHITE);
display.drawPixel(ox+12, oy+5, SH110X_WHITE);
display.drawPixel(ox+11, oy+6, SH110X_WHITE);
// --- NOS (kwadrat)
display.drawPixel(ox+7, oy+6, SH110X_WHITE);
display.drawPixel(ox+7, oy+7, SH110X_WHITE);
display.drawPixel(ox+8, oy+6, SH110X_WHITE);
display.drawPixel(ox+8, oy+7, SH110X_WHITE);
// --- ZĘBY
display.drawPixel(ox+4, oy+9, SH110X_WHITE);
display.drawPixel(ox+6, oy+9, SH110X_WHITE);
display.drawPixel(ox+9, oy+9, SH110X_WHITE);
display.drawPixel(ox+11, oy+9, SH110X_WHITE);
// --- PISZCZEL
display.drawLine(ox+3, oy+14, ox+12, oy+14, SH110X_WHITE);
display.drawLine(ox+3, oy+12, ox+12, oy+12, SH110X_WHITE);
display.drawPixel(ox+1, oy+11, SH110X_WHITE);
display.drawPixel(ox+2, oy+11, SH110X_WHITE);
display.drawPixel(ox+13, oy+11, SH110X_WHITE);
display.drawPixel(ox+14, oy+11, SH110X_WHITE);
display.drawPixel(ox+1, oy+15, SH110X_WHITE);
display.drawPixel(ox+2, oy+15, SH110X_WHITE);
display.drawPixel(ox+13, oy+15, SH110X_WHITE);
display.drawPixel(ox+14, oy+15, SH110X_WHITE);
display.drawPixel(ox+0, oy+12, SH110X_WHITE);
display.drawPixel(ox+1, oy+13, SH110X_WHITE);
display.drawPixel(ox+0, oy+14, SH110X_WHITE);
display.drawPixel(ox+15, oy+12, SH110X_WHITE);
display.drawPixel(ox+14, oy+13, SH110X_WHITE);
display.drawPixel(ox+15, oy+14, SH110X_WHITE);
}
void draw(){
display.clearDisplay();
//draw map
for (int i = 0; i<WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
uint8_t tile = getTile(i, j);
if (tile==1||tile==2) display.drawPixel(2*i, 2*j, SH110X_WHITE);
if (tile==1||tile==2) display.drawPixel(2*i, 2*j+1, SH110X_WHITE);
if (tile==1||tile==2) display.drawPixel(2*i+1, 2*j, SH110X_WHITE);
if (tile==1||tile==2) display.drawPixel(2*i+1, 2*j+1, SH110X_WHITE);
}
}
drawPlayer();
//draw dash trail
if (tDash>0){
display.drawLine(2*xDtemp1, 2*yDtemp1, 2*xDtemp2, 2*yDtemp2, SH110X_WHITE);
tDash -=1;
}
if(levelNum>0){
drawTimer();
}else{
display.setTextColor(SH110X_WHITE);
display.setTextSize(1);
display.setCursor(10, 45);
display.print("by: PCh & Zgirak");
}
if(levelNum==4)drawSkull();
display.display();
}
void checkHitbox(){
//next level
if (getTile(x, y)==3 ||getTile(x, hy)==3){
levelNum += 1;
levelStart(levelNum);
}
//death
if (getTile(x, y)==2 ||getTile(x, hy)==2 || y==31){
levelStart(levelNum);
deathCount += 1;
}
//check for floor
if (getTile(x, y+1)==1){
onGround = true;
ableToDash = true;
ableToJump = true;
tempJump = true;
ableToRun = true;
vy = 0;
}else{
onGround = false;
ableToJump = false;
vy -=1;
}
onWallLeft = (getTile(x-1, y-1)==1);
onWallRight = (getTile(x+1, y-1)==1);
}
void loop() {
checkHitbox();
readInput();
movement();
draw();
delay(1);
if(levelNum!=4&&levelNum!=0)time += 0.1;