Forums
pong watch - Printable Version

+- Forums (http://forum.zakkemble.co.uk)
+-- Forum: Project discussion (http://forum.zakkemble.co.uk/forum-4.html)
+--- Forum: N|Watch (DIY Digital Wristwatch) (http://forum.zakkemble.co.uk/forum-6.html)
+--- Thread: pong watch (/thread-13.html)



pong watch - chang - 12-27-2014

I've adapted the breakout game code to mimic the original pong watch.




Here is what it looks like. The score shows the time.
[attachment=5]

Here is the code. Just replace the code in normal.c in the firmware/src/watch/watchface folder. Then "make all" with my makefile in the src/watch folder and then "make program" to load in your watch.
The code is hacked together from my limited understanding of bitmaps and I've changed the direction of the game without changing the variable names. But it seems to work. If someone wants to add the dashed center line, I would really appreciate it.
Code:
/*
* Project: N|Watch
* Author: Zak Kemble, contact@zakkemble.co.uk
* Copyright: (C) 2013 by Zak Kemble
* License: GNU GPL v3 (see License.txt)
* Web: http://blog.zakkemble.co.uk/diy-digital-wristwatch/
*/

/* Pong watchface, based on breakout code */

#include "common.h"

#define PLATFORM_WIDTH  12
#define PLATFORM_HEIGHT 4

typedef struct{
       float x;
       float y;
       float velX;
       float velY;
}s_ball;

static const byte platform[] PROGMEM ={
 0x0F,0x0F,
};

static const byte ballImg[] PROGMEM ={
       0x03,0x03,
};

static s_ball ball;
static byte lives=0;
static uint score;
static byte platformX;
static byte cplatformX; // computer platform position

static void game_start(void);
static display_t draw(void);

void watchface_normal()
{
 if (lives == 0){
   game_start();
 }
 display_setDrawFunc(draw);
 buttons_setFuncs(NULL, menu_select, NULL);
 animation_start(NULL, ANIM_MOVE_ON);
}

void game_start()
{
       menu_close();

       srand(millis());

       display_setDrawFunc(draw);
       //      buttons_setFuncs(btnRight, btnExit, btnLeft);

       ball.y = FRAME_WIDTH / 2;
       ball.x = FRAME_HEIGHT - 10;
       ball.velX = -1;
       ball.velY = -1.1;

       //      blocks = calloc(BLOCK_COUNT, 1);
       
       lives = 3;
       score = 0;
       platformX = (FRAME_HEIGHT / 2) - (PLATFORM_WIDTH / 2);
       cplatformX = ball.x;
}

static display_t draw()
{
       byte platformXtmp = platformX;
       platformXtmp = ball.x - PLATFORM_WIDTH/2;

       // Make sure platform stays on screen
       if(platformXtmp > 250-10)
               platformXtmp = 1;
       else if(platformXtmp > FRAME_HEIGHT - PLATFORM_WIDTH)
               platformXtmp = FRAME_HEIGHT - PLATFORM_WIDTH;

       // Draw platform
       image_s img = newImage(FRAME_WIDTH - 2, platformXtmp, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(FRAME_WIDTH - 2, platformXtmp+2, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(FRAME_WIDTH - 2, platformXtmp+4, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(FRAME_WIDTH - 2, platformXtmp+6, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(FRAME_WIDTH - 2, platformXtmp+8, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       
       platformX = platformXtmp;

       // Move ball
       ball.x += ball.velX;
       ball.y += ball.velY;

       const byte ballX = ball.x;
       const byte ballY = ball.y;

       // Side wall collision
       cplatformX = ball.x - PLATFORM_WIDTH/2;
       platformXtmp = cplatformX;

       // Make sure platform stays on screen
       if(platformXtmp > 250-10)
               platformXtmp = 1;
       else if(platformXtmp > FRAME_HEIGHT - PLATFORM_WIDTH)
               platformXtmp = FRAME_HEIGHT - PLATFORM_WIDTH;

       img = newImage(0, platformXtmp, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(0, platformXtmp+2, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(0, platformXtmp+4, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(0, platformXtmp+6, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);
       img = newImage(0, platformXtmp+8, platform, 2, 8, WHITE, NOINVERT, 0);
       draw_bitmap_set(&img);
       draw_bitmap_s2(&img);

       if(ballX > FRAME_HEIGHT - 2)
       {
               if(ballX > 240)
                       ball.x = 2;            
               else
                       ball.x = FRAME_HEIGHT - 2;
               ball.velX *= -1;                
       }

       // Platform collision
       bool platformCollision = false;
       if(ballY >= FRAME_WIDTH - PLATFORM_HEIGHT && ballY < 250 && ballX >= platformX && ballX <= platformX + PLATFORM_WIDTH)
       {
               platformCollision = true;
               buzzer_buzz(200, TONE_5KHZ, VOL_UI, PRIO_UI, NULL);
               ball.y = FRAME_WIDTH - PLATFORM_HEIGHT;
               if(ball.velY > 0)
                       ball.velY *= -1;
               ball.velX = ((float)rand() / (RAND_MAX / 2)) - 1; // -1.0 to 1.0
       }
       // Platform collision2
       bool platformCollision = false;
       if(ballY >= FRAME_WIDTH - PLATFORM_HEIGHT && ballY < 250 && ballX >= platformX && ballX <= platformX + PLATFORM_WIDTH)
       {
               platformCollision = true;
               buzzer_buzz(200, TONE_5KHZ, VOL_UI, PRIO_UI, NULL);
               ball.y = FRAME_WIDTH - PLATFORM_HEIGHT;
               if(ball.velY > 0)
                       ball.velY *= -1;
               ball.velX = ((float)rand() / (RAND_MAX / 2)) - 1; // -1.0 to 1.0
       }
       // Platform collision2
       platformCollision = false;
       if(ballY <= 2 && ballY > 0 && ballX >= cplatformX && ballX <= cplatformX + PLATFORM_WIDTH)
       {
               platformCollision = true;
               buzzer_buzz(200, TONE_5KHZ, VOL_UI, PRIO_UI, NULL);
               ball.y = PLATFORM_HEIGHT;
               if(ball.velY < 0)
                       ball.velY *= -1;
               ball.velX = ((float)rand() / (RAND_MAX / 2)) - 1; // -1.0 to 1.0
       }


       // Top/bottom wall collision
       if(!platformCollision && (ballY > FRAME_WIDTH - 2))
       {
               ball.velY *= -1;
       }

       // Draw ball
       img.bitmap = ballImg;
       img.width = 2;
       img.x = ball.y;
       img.y = ball.x;
       draw_bitmap_s2(&img);

       draw_string(time_timeStr(), false, 48, 1);
       return DISPLAY_DONE;
}