Odbijająca się 'piłka' w oknie

0

Cześć!

Otóż chcę zrobić coś takiego, by w oknie odbijała się cały czas piłeczka, niestety natrafiłem na problem i nie wiem jak go rozwiązać, dlatego zwracam się z prośbą o pomoc do Was. Otóż zanim piłka się nie odbije o dolną ściankę okna wszystko jest okej, niestety potem nie wiem co dalej. Próbowałem na kilka sposobów to zrobić i niestety nie wpadłem na nic ciekawego. Nie chcę szukać gotowców w internecie, tylko chcę dojść do tego po części sam, dlatego prosiłbym o jakąś wskazówkę/radę, co robię nie tak.
Chodzi dokładnie o wartość odbicie, gdy przyjmuje wartość 2.
Pozdrawiam
Kod wygląda tak:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if(y+wielkosc<Form1.Height) and (Form1.Width > x+wielkosc) then odbicie:=1
else if(y+wielkosc>=Form1.Height) then odbicie:=2
else if(x+wielkosc>=Form1.Width) then odbicie:=3;
case odbicie of
1: begin x:=x+1; y:=y+1; Form1.Canvas.Ellipse(x, y, wielkosc+x, wielkosc+y); end;
2: begin x:=x+1; y:= Form1.ClientHeight; y:=y-1; Form1.Canvas.Ellipse(x, y, wielkosc+x, y+wielkosc); end;
// 2: begin x:=x+1; y:=0; y:=y+1; Form1.Canvas.Ellipse(x, y, wielkosc+x, Form1.Height-(y+wielkosc)); end;
3: begin x:=x-1; y:=y+1; end;
end;
end;
2

Zapisuj prędkość jako wektor.

0

@Tytanowyy - podaj więcej informacji na temat odbijania się tej piłeczki; Mam na myśli wielkość piłeczki, dozwolone kierunki odbicia, wysokość odbicia itd.; Poza tym przydałoby się, abyś podał w miarę cały kod, aby można go było przetestować i poprawić lokalnie.

0

Bardzo proszę, wczoraj jeszcze trochę nad tym posiedziałem i doszedłem chociaż po części do tego co źle - mianowicie dodałem sobie 2 komponenty edit.text i zauważyłem, że problem jest z warunkiem wykonującym się co sekundę:

 if(y+wielkosc<Form1.Height) and (Form1.Width > x+wielkosc) then rysuj_dol_prawo(x,y,sender)
  else if(x+wielkosc>=Form1.Width) then rysuj_dol_lewo(x,y,sender)

Przecież ten warunek wykona się tylko raz, przy dotknięciu i potem powróci co warunku wyżej, niestety nie wiem teraz jak zrobić, by program wiedział, że akurat odbił się od dołu. 2 Zmienne prawda/fałsz by zaznaczać sobie nimi dotknięcie góra-dół / lewo-prawo?
Dorobiłem sobie procedury, odpowiedzialne za rysowanie piłki z każdego rogu by sprawdzić, czy poruszają się w dobrych kierunkach i poruszają się dobrze. Tutaj dołączam kod

@Patryk27, dzięki za podpowiedź, lecz niestety wektorów w szkole jeszcze nie przerabialiśmy i nawet nie wiem, czy będziemy a facet zaproponował bym się może pobawił i zrobił coś na wzór gry 'ping pong', tylko najpierw muszę rozgryźć problem odbijania się piłeczki. Zaproponował mi do tego użycie komponentu Timer.

Pozdrawiam serdecznie

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;
const wielkosc = 50;
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
   procedure rysuj_gora_prawo(x,y :integer; Sender: TObject);
   procedure rysuj_gora_lewo(x,y :integer;Sender: TObject);
   procedure rysuj_dol_prawo(x,y :integer;Sender: TObject);
   procedure rysuj_dol_lewo(x,y :integer;Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  x,y, odbicie:integer;
  last:integer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
x := 0;
y := 0;
odbicie := 0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
x:=x+1; y:=y+1; Edit1.Text := FloatToStr(x); Edit2.Text := FloatToStr(y);
  if(y+wielkosc<Form1.Height) and (Form1.Width > x+wielkosc) then rysuj_dol_prawo(x,y,sender)
  else if(x+wielkosc>=Form1.Width) then rysuj_dol_lewo(x,y,sender)
  else if(y+wielkosc>=Form1.Height) then rysuj_dol_lewo(x,y,sender)
  else if(y+wielkosc<=0) then rysuj_dol_prawo(x,y,sender)
  else if(x+wielkosc<=0) then rysuj_dol_prawo(x,y,sender);
end;


procedure TForm1.rysuj_gora_prawo(x,y :integer;Sender: TObject);
begin
Form1.Canvas.Ellipse(x, Form1.Height-y, wielkosc+x, Form1.Height-(wielkosc+y));
end;

procedure TForm1.rysuj_gora_lewo(x,y :integer;Sender: TObject);
begin
Form1.Canvas.Ellipse(Form1.Width-x, Form1.Height-y, Form1.Width-(wielkosc+x), Form1.Height-(wielkosc+y));
end;

procedure TForm1.rysuj_dol_prawo(x, y:integer; Sender: TObject);
begin
Form1.Canvas.Ellipse(x, y, wielkosc+x, wielkosc+y);
end;

procedure TForm1.rysuj_dol_lewo(x,y :integer;Sender: TObject);
begin
Form1.Canvas.Ellipse(Form1.Width-x, y, Form1.Width-(wielkosc+x), wielkosc+y);
end;
end.
1

Zmienne prawda/fałsz by zaznaczać sobie nimi dotknięcie góra-dół / lewo-prawo?

Nie, wektory.

dzięki za podpowiedź, lecz niestety wektorów w szkole jeszcze nie przerabialiśmy i nawet nie wiem, czy będziemy

W kija rzeczy nie będziecie przerabiać - bycie informatykiem (a tym bardziej programistą!) polega na uczeniu się na własną rękę.
Zatem trzymaj: http://pl.wikipedia.org/wiki/Wektor

0

Ok, dzięki w takim razie zabieram się za lekturę, jednakże proszę jeszcze nie zamykać tematu, jeżeli będzie taka potrzeba, to poproszę o pomoc :)

Pozdrawiam

0

Ale wszyscy kombinujecie. Jak to ma być zaliczenie do szkoły to wystarczy sprawdzenie kolizji i zmiana znaku prędkości w timerze.

begin
  pozycja := pozycja + predkosc;
  if kolizja then
    predkosc := predkość * (-1);
end;
 
0
  1. Potraktuj pilke jako pojedynczy punkt. Rozwiaz zadanie fizycznie: vx, vy , x,y. Zapisz wzory itp.
  2. Zapisz Rozmiary: promien pilki, szerokosc okna, wysokosc okna. Zapisz wzory na odleglosc pilki od kazdej krawedzi.
  3. Zaimplementuj kolizje (po kolizji zmienia sie jedynie predkosc)

Z mojego doswiadczenia na drodze na skroty spedzisz 5x tyle czasu debugujac.

0

Kiedyś na studiach pisałem coś podobnego i (o dziwo nadal mam ten projekt na dysku). W załączeniu cały projekt mam nadzieje, że Ci to pomoże:

1 użytkowników online, w tym zalogowanych: 0, gości: 1