This week, we were supposed to start working on the final project right after finalizing our proposals. The link to the proposal for the game Ngoc and I are working on can be found below.
Update: Wednesday 14th April – Sunday 18th April
Ngoc and I sat down and discussed the Processing part of the game. Based on our past experience of working on games, we had slightly different opinions on how to go about the classes our game would contain, but there’s a lot I can learn from a sophomore and I believed that her idea of creating 4 different classes would make it easier for us to work on different parts of the game. The 4 classes and a description of what all of them would do are as follows:
- Item
The Item
Class will consist of all attributes of items which are to fall down the screen. These attributes will include the initial x and y coordinates of the items, their velocities as they fall down the screen, radii, image (to be displayed for each item) and more. The Item
Class will also consist of relevant methods for all items, including their update()
and display()
methods.
- Player
The Player
class will characterize the user of the Processing program. The most fundamental attribute of a Player
object is the x coordinate which is communicated from the Arduino program and updated accordingly. It will also have a display()
method to show where the player is on the screen (represented by a sprite). Other information will also be communicated between different classes like Player
, Level
, Game
to determine when the player will appear on the screen etc.
- Level
A Level
object encompasses one full game level and includes a number of objects from other classes, for example one level
will include one player
and multiple item
s, as well as new entities like performance metrics. This class coordinates the interactions between Item
class and Player
class like checking for collisions, and supports other key game functionalities like updating and displaying performances.
- Game
An instance of the Game
class will represent one entire game which will have four level
s, each corresponding to one of the four academic years. It will also contain its own update()
and display()
functions, which will coordinate certain conditions and outputs to deal with those conditions. Moreover, it will also be responsible for calling the update()
functions of other objects which are instantiated within the Game
class and the Level
class.
Remote Control Testing
The part we expect to be the hardest is getting the remote control to work. From working on previous assignments, we have seen that the distance measuring sensor gives pretty unstable readings and we were concerned with how that might reflect in our program, since smooth and correct mapping of the movement of the remote control onto the screen is a key game function.
We first experimented with mapping the distance onto the movement of a circle on a blank screen to make sure that we could get the sensor to work as we want. As expected, the movement of the circle was quite jittery and glitchy, but it did move in the way we intended. So this proved that we could indeed move the whole Arduino and breadboard combination as a remote control for the game.
We then experimented further with the Processing code to smoothen the movement of the player (which is still represented by a single moving circle for the sake of simplicity). We went back to an earlier example and used it in our Processing code, which gave much smoother player movement.
The differences between no smoothing vs. with smoothing are recorded as can be seen in the short demo:
The Arduino and Processing code for testing the remote control is as following:
GitHub link: https://github.com/nhungoc1508/not-so-creative-final-project/tree/master/remote-control
Arduino code:
const int trigPin = 11; const int echoPin = 12; float distance; void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("0"); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { // put your main code here, to run repeatedly: // distance = getDistance(); // Serial.println(distance); while (Serial.available()) { if (Serial.read() == '\n') { distance = getDistance(); delay(1); Serial.println(distance); } } } float getDistance() { float echoTime; //variable to store the time it takes for a ping to bounce off an object float calculatedDistance; //variable to store the distance calculated from the echo time //send out an ultrasonic pulse that's 10ms long digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); echoTime = pulseIn(echoPin, HIGH); //use the pulsein command to see how long it takes for the //pulse to bounce back to the sensor // calculatedDistance = echoTime / 148.0; //calculate the distance of the object that reflected the pulse (half the bounce time multiplied by the speed of sound) calculatedDistance = echoTime / 58.0; return calculatedDistance; //send back the distance that was calculated }
Processing code:
import processing.serial.*; Serial myPort; float xPos=0; float yPos; float smoothedNum = 0; float prevX=0; void setup() { //size(960, 720); fullScreen(); yPos=height/2; //printArray(Serial.list()); String portname=Serial.list()[4]; //[4] "/dev/cu.usbmodem1101" //println(portname); myPort = new Serial(this, portname, 9600); myPort.clear(); myPort.bufferUntil('\n'); } void draw() { background(255); fill(100, 200, 200); noStroke(); if (abs(xPos-smoothedNum) < width*.3) { smoothedNum += (xPos-smoothedNum)*.2; } ellipse(smoothedNum, yPos, 50, 50); prevX = smoothedNum; } void serialEvent(Serial myPort) { String s=myPort.readStringUntil('\n'); s=trim(s); if (s!=null) { println(s); int value = int(s); println(value); xPos=(float)map(value, 0, 50, 0, width); } myPort.write("\n"); }