#include "paddle.h"
#include <iostream>
bool Paddle::init()
{
p = new Position();
p->x = 0.0;
p->y = SCREEN_HEIGHT/2.0;
v = new Velocity();
v->x = 4.0;
v->y = 4.0;
image = al_load_bitmap("paddle1.png");
if (!image) {
std::cout<<"in padd init!"<<std::endl;
return false;
}
return true;
}
ALLEGRO_BITMAP* Paddle::getBitmap()
{
return image;
}
float Paddle::getHeight()
{
return al_get_bitmap_height(image);
}
float Paddle::getWidth()
{
return al_get_bitmap_width(image);
}
Position* Paddle::getPosition()
{
return p;
}
Velocity* Paddle::getVelocity()
{
return v;
}
void Paddle::move(ALLEGRO_KEYBOARD_STATE* keyState)
{
if ( al_key_down(keyState, ALLEGRO_KEY_DOWN) ) {
if(p->y+getHeight() < SCREEN_HEIGHT ) {
p->y += v->y;
}
} else if ( al_key_down(keyState, ALLEGRO_KEY_UP) ) {
if ( (p->y - v->y) >= 0 ) {
p->y -= v->y;
}
}
}
void Paddle::draw()
{
al_draw_bitmap(image, p->x, p->y,0);
} 2. AiPaddle.cpp code:
#include "ai_paddle.h"
#include <iostream>
bool AiPaddle::init()
{
p = new Position();
p->y = SCREEN_HEIGHT/2.0;
v = new Velocity();
v->x = 4.0;
v->y = 4.0;
image = al_load_bitmap("paddle1.png");
p->x = SCREEN_WIDTH - al_get_bitmap_width(image);
if (!image) {
std::cout<<"in padd init!"<<std::endl;
return false;
}
return true;
}
ALLEGRO_BITMAP* AiPaddle::getBitmap()
{
return image;
}
float AiPaddle::getHeight()
{
return al_get_bitmap_height(image);
}
float AiPaddle::getWidth()
{
return al_get_bitmap_width(image);
}
Position* AiPaddle::getPosition()
{
return p;
}
Velocity* AiPaddle::getVelocity()
{
return v;
}
void AiPaddle::move(ALLEGRO_KEYBOARD_STATE* keyState)
{
if ( al_key_down(keyState, ALLEGRO_KEY_DOWN) ) {
if(p->y+getHeight() < SCREEN_HEIGHT ) {
p->y += v->y;
}
} else if ( al_key_down(keyState, ALLEGRO_KEY_UP) ) {
if ( (p->y - v->y) >= 0 ) {
p->y -= v->y;
}
}
}
void AiPaddle::draw()
{
al_draw_bitmap(image, p->x, p->y,0);
}
void AiPaddle::update(Velocity* ball_velocity, Position* ball_position)
{
if ( ball_velocity->x > 0 ) {
if ( ball_velocity->y > 0 && p->y + getHeight() < ball_position->y ) {
if(p->y+getHeight() < SCREEN_HEIGHT ) {
p->y += v->y;
}
} else {
if ( (p->y - v->y) >= 0 && p->y > ball_position->y ) {
p->y -= v->y;
}
}
}
}
3.Ball.cpp code:
#include "ball.h"
bool Ball::init()
{
p = new Position();
p->x = 0.0;
p->y = 200.0;
v = new Velocity();
v->x = 3.0;
v->y = 2.0;
image = al_load_bitmap("ball1.png");
if(!image) {
return false;
}
return true;
}
bool Ball::collisionWithWall()
{
bool collision_flag = false;
if ( p->y <= 0 || p->y + getHeight() >= SCREEN_HEIGHT ) {
collision_flag = true;
}
return collision_flag;
}
bool Ball::collisionWithPaddles(Paddle* pd, AiPaddle* aipd)
{
bool collision_flag = false;
if( p->y >= pd->getPosition()->y && p->y <= (pd->getPosition()->y+pd->getHeight()) ) {
if ( p->x <= (pd->getPosition()->x+pd->getWidth()) ) {
collision_flag = true;
}
} else if ( p->y >= aipd->getPosition()->y && p->y <= (aipd->getPosition()->y+aipd->getHeight()) ) {
if ( p->x+getWidth() >= (aipd->getPosition()->x) ) {
collision_flag = true;
}
}
return collision_flag;
}
void Ball::update(Paddle* pd, AiPaddle* aipd)
{
if ( collisionWithPaddles(pd, aipd) ) {
v->x = -v->x;
} else if ( p->y <= 0 || p->y + getHeight() >= SCREEN_HEIGHT ) {
v->y = -v->y;
}
p->x += v->x;
p->y += v->y;
}
Position* Ball::getPosition()
{
return p;
}
Velocity* Ball::getVelocity()
{
return v;
}
void Ball::draw()
{
al_draw_bitmap(image, p->x, p->y, 0);
}
float Ball::getHeight()
{
return al_get_bitmap_height(image);
}
float Ball::getWidth()
{
return al_get_bitmap_width(image);
}
4. Main function:
#include <iostream>
#include <stdio.h>
#include <allegro5/allegro.h>
#include "allegro5/allegro_image.h"
#include "allegro5/allegro_native_dialog.h"
#include "ball.h"
#include "ai_paddle.h"
#include <iostream>
using namespace std;
const float FPS = 60;
const int BOUNCER_SIZE = 32;
enum MYKEYS { KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT };
int main(int argc, char** argv)
{
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE* event_queue = NULL;
ALLEGRO_TIMER* timer = NULL;
bool redraw = true;
bool doexit = false;
bool key[4] = {false, false, false, false };
ALLEGRO_KEYBOARD_STATE keyState;
if(!al_init()) {
fprintf(stderr, "failed to initialize!");
return -1;
}
if(!al_init_image_addon()) {
al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!",
NULL, ALLEGRO_MESSAGEBOX_ERROR);
return 0;
}
if(!al_install_keyboard()) {
fprintf(stderr, "failed to initialize keyboard!");
return -1;
}
timer = al_create_timer(1.0/FPS);
if(!timer) {
fprintf(stderr, "failed to initialize timer!");
return -1;
}
display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT);
if(!display) {
fprintf(stderr, "display failed to initialize!");
return -1;
}
event_queue = al_create_event_queue();
if(!event_queue) {
fprintf(stderr, "failed to create event_queue!\n");
al_destroy_display(display);
al_destroy_timer(timer);
return -1;
}
Paddle paddle;
if ( !paddle.init() ) {
cout<<"error";
return -1;
}
Ball ball;
if ( !ball.init() ) {
return -1;
}
AiPaddle aipaddle;
if( !aipaddle.init() ) {
return -1;
}
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_start_timer(timer);
while(!doexit) {
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if ( ev.type == ALLEGRO_EVENT_TIMER ) {
al_get_keyboard_state(&keyState);
paddle.move(&keyState);
ball.update(&paddle, &aipaddle);
aipaddle.update( ball.getVelocity(), ball.getPosition() );
redraw = true;
} else if ( ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE ) {
break;
} else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
switch(ev.keyboard.keycode) {
case ALLEGRO_KEY_ESCAPE:
doexit = true;
break;
}
}
if(redraw && al_is_event_queue_empty(event_queue)) {
redraw = false;
al_clear_to_color(al_map_rgb(0,0,0));
ball.draw();
paddle.draw();
aipaddle.draw();
al_flip_display();
}
}
return 0;
}
Along with these, i created a global header file, in which i put common structs:
#ifndef GLOBAL_H
#define GLOBAL_H
#include "allegro5/allegro.h"
#include "allegro5/allegro_image.h"
struct Position {
float x;
float y;
};
struct Velocity {
float x;
float y;
};
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#endif
The problem is, sometimes the ball goes through the AI paddle, dont seem to get it why.
Other issue is, sometimes the ball collides the player paddle but it just doesn't change the direction. It would be helpful if you could point out the error or where I'm going wrong.
Thank you!