OOP dag 10

Øvelser

5.6.2 Opgaver

  1. Ret SpilMatador til at bruge Rederi2 og Gade2 i stedet for Rederi og Gade. Kør programmet, og følg med i, hvad der sker i Gade2's konstruktør og landet()-metode.

  2. Føj en Bryggeri-klasse til matadorspillet version 2. Husk at kalde super() i konstruktøren (hvorfor er det nødvendigt?). Du kan evt. kopiere Gade2.java i stedet for at skrive koden forfra. Hvor meget kode kan du spare?

  3. Ret på Spiller, så slag er en objektvariabel i stedet for en lokal variabel. Nu kan man udefra aflæse, hvad spilleren slog sidst. Brug værdien af slag i landet()-metoden i Bryggeri til at lade lejen afhænge af, hvad spilleren slog.

Hvis der er tid (og lyst)

9.3.1 Opgave: Grafisk Matador-spil

Lav matadorspillet om til at kunne vises grafisk i et vindue ved at definere en tegn()-metode i hvert Felt og kalde den fra vinduets paint().
Lad programmet spille en tur hvert sekund (kald repaint(1000) fra paint()-metoden) eller lad brugeren styre (se afsnit 2.12.2).

Vink

Når du skal programmere, så vær systematisk, og del opgaven op i små delopgaver. Løs en delopgave ad gangen, og afprøv, at det fungerer, før du går videre.

  1. Hent kildeteksten til matadorspillet (version 2: Felt.java, Gade2.java, Grund2.java, Helle.java, Rederi2.java, Start.java, Spiller.java og SpilMatador.java ændret til at bruge Gade2 og Rederi2), og prøv det.

  2. Genbrug GrafiskVindue ovenfor. Lad initialisering ske i konstruktøren. Variabler, der skal deles mellem flere metoder, skal være objektvariabler (de lokale eksisterer jo kun i den metode, de er defineret i).

  3. Føj en metode til Felt, der tegner feltet. Hvert felt skal også have en position (den er en del af initialiseringen, så sæt den fra konstruktøren).

  4. Løb igennem alle felter, og tegn dem i paint().

  5. Udbyg derefter spillet efter egen smag. Tegn f.eks. også spillerne og deres biler.

Flere vink og løsningsforslag

Det er bedst, at du bruger hovedet og kun ser på vinkene, hvis du er gået i stå.

  1. Prøve programmet.
    Har du ikke allerede i sidste lektion prøvet matadorspillet, så prøv at køre programmet. Derefter er det naturligvis meget lettere at lave en grafisk udgave! Brug trinvis gennemgang (trace into/step over), indtil du føler, du har forstået programkoden. Først da er du klar til at prøve grafisk.

  2. Struktur i et grafisk vindue.
    Flyt initialiseringen fra SpilMatador.java til konstruktøren af GrafiskVindue. Husk at importere java.util.* øverst for at få adgang til Vector-klassen. Variablerne felter, sp1, sp2 skal nu være objektvariabler (før var de lokale variabler), for at de kan ses i resten af objektet:

import java.awt.*;
import java.util.*;
public class GrafiskVindue extends Frame
{
// objektvariabler:
Spiller sp1=new Spiller("Søren",50000,Color.green); // opret spiller 1
Spiller sp2=new Spiller("Gitte",50000,Color.yellow); // opret spiller 2
Vector felter=new Vector();

public GrafiskVindue()
{
felter.addElement(new Start(5000));
felter.addElement(new Gade2("Gade 1",10000, 400,1000));
felter.addElement(new Gade2("Gade 2",10000, 400,1000));
//... osv.

Husk, at vinduet først tegnes, når initialiseringen er færdig, så hvis du f.eks. kører 20 runder i initialiseringen, tager det lang tid, førend systemet når til at kalde paint()!

  1. Hvert felt skal have en position. Føj en position (af typen Point) til Felt-klassen:

import java.awt.*; 
public class Felt
{
String navn;
Point position = new Point();

og definér metoden tegn(Graphics g) på Felt, der tegner feltets navn på positionen:

  public void tegn(Graphics g) 
{
g.setColor(Color.black);
g.drawString(navn,position.x,position.y);
}

Husk at importere java.awt.* øverst for at få adgang til Point- og Graphics-klassen.

Løb alle felterne igennem i konstruktøren, og sæt koordinaterne på felterne:

    felter.addElement(new Gade2("Gade 8",20000,1100,2000)); 
felter.addElement(new Gade2("Gade 9",30000,1500,2200));
for (int i=0; i<felter.size(); i++)
{
double v = Math.PI*2*i/felter.size(); // vinkel i radianer
Felt f = (Felt) felter.elementAt(i);
f.position = new Point(
100 + (int) (100*Math.cos(v)),
110 + (int) (100*Math.sin(v))
);
}
  1. Definér vinduets paint()-metode til at kalde felternes tegn() for at tegne brættet:

  public void paint(Graphics g) 
{
for (int i=0; i<felter.size(); i++)
{
Felt f = (Felt) felter.elementAt(i);
f.tegn(g);
}

En grund skal også have tegnet ejeren nedenunder, så den skal have en anderledes tegn(). Definér tegn() i Grund2. En gade skal også vise antallet af huse. Definér også tegn() i Gade2. 

Hvis du er gået helt i stå

Kan du slet ikke komme videre så er der mulighed for at kigge i et forslag til løsning.