'낙서장' 카테고리의 다른 글

동기화의 의미  (0) 2020.05.15
200513  (0) 2020.05.13
프로젝트 제작시 폴더 구분  (0) 2020.04.28
자바 네이버 지도 api 사용하기 (프로젝트 대비)  (0) 2020.04.27
200424  (0) 2020.04.24

개요

 

 

*설계할때에는 먼저 테이블을 만들어야하는데 최근에는 자바에서 클래스로 모델을 먼저 만드는 경우도 있다고 한다.

*모델마다 dao가 필요하다는 점 꼭 참고하자

 

 

그룹을 스트링으로하면 도메인설정이 되지 않는다.

아래에서 enum으로 설정하는 법을 알아보자.

 

 

enum을 쓰면 강제성이 생긴다.

 

타입을 지정해버리면 다른 타입을 넣을 수 없다.

 

group타입을 이넘으로 바꾸자

 

싱글톤으로 MemberDao 제작

 

빌드패스

 

 

테스트를 위한 내부라이브러리 빌드패스

 

JUnit은 일부 메서드를 테스트하기위한 기능이다.

 

일단 4번을 쓰자

 

스태틱이면 안되고 void여야한다고 에러가남(참고만하자)

 

테스트 파일을 하나 만들어서 아까 것을 테스트 해본다.

 

 

정상이면 빨강이다.

 

 

DBUtils에는 DB에 필요한 부가기능들을 넣자

 

gui

package address.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import address.model.GroupType;
import address.model.Member;

public class MainFrame extends JFrame {
	
	
	private JFrame mainFrame = this;
	
	private Container backgroundPanel;
	
	private JPanel topPanel, menuPanel, listPanel;
	
	private JButton homeButton, frButton, coButton, scButton, faButton, addButton;
	
	private JList<Member> userList;
	
	private DefaultListModel<Member> listModel; // Jlist에 이것을 넣어야 한다.
	
	private JScrollPane jsPane;
	
	public MainFrame() {
		initObject();
		initData();
		initDesign();
		initListener();
		setVisible(true);
	}
	
	// new
	private void initObject() {
		backgroundPanel = getContentPane();
		
		topPanel = new JPanel();
		menuPanel = new JPanel();
		listPanel = new JPanel();
		
		homeButton = new JButton("주소록 전체");
		frButton = new JButton("친구");
		coButton = new JButton("회사");
		scButton = new JButton("학교");
		faButton = new JButton("가족");
		addButton = new JButton("추가");
		
		listModel = new DefaultListModel<>();
		userList = new JList<>(listModel);
		
		jsPane = new JScrollPane(userList); // 뒤의 패널색깔을 유지하려면 그냥 ScrollPane을 이용하자
	}
	
	// 데이터 초기화
	private void initData() {
		for (int i = 1; i < 31; i++) {
			listModel.addElement(new Member(i, "홍길동", "0102222", "부산시", GroupType.친구));
		}
	}
	
	// 디자인
	private void initDesign() {
		// 1. 기본세팅
		setTitle("주소록 메인");
		setSize(400, 500);
		setLocationRelativeTo(null); // 모니터 중앙에 배치
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// 2. 패널세팅
		backgroundPanel.setLayout(new BorderLayout());
		topPanel.setLayout(new GridLayout(2,1));
		menuPanel.setLayout(new GridLayout(1,4));
		listPanel.setLayout(new BorderLayout());
		
		// 3. 디자인
		userList.setFixedCellHeight(50); // 리스트각각의 높이
		topPanel.setPreferredSize(new Dimension(0, 100)); // 그리드레이아웃이라 가로를 0으로해도 자동으로 꽉차게된다.
		
		// 4. 패널에 컴포넌트 추가
		menuPanel.add(frButton);
		menuPanel.add(coButton);
		menuPanel.add(scButton);
		menuPanel.add(faButton);
		
		listPanel.add(jsPane);
		
		topPanel.add(homeButton);
		topPanel.add(menuPanel);
		
		backgroundPanel.add(topPanel, BorderLayout.NORTH);
		backgroundPanel.add(listPanel, BorderLayout.CENTER);
		backgroundPanel.add(addButton, BorderLayout.SOUTH);
	}
	
	// 리스너 등록
	private void initListener() {
		
	}
}

 

 

MERGE : 위아래 병합

TRUNCATE : 잘라내기

ROLLBACK : 취소

----------------------------

트랜잭션 - 의미 있는 단위로 작업을 나누는 것

-----------------------------

-----------------------------

 

테이블을 복사하여 가져오기 (AS)

CREATE TABLE DEPT6
AS
SELECT DCODE, DNAME
FROM DEPT2
WHERE DCODE IN(1000,1001,1002);

 

테이블에 속성 추가하기

ALTER TABLE DEPT6
ADD (LOCATION VARCHAR2(10));

 

LOCATION2 속성을 추가하면서 기본값을 SEOUL로 만들기

ALTER TABLE DEPT6
ADD (LOCATION2 VARCHAR2(10) DEFAULT 'SEOUL');

 

LOCATION2 속성이름을 LOC로 만들기

ALTER TABLE DEPT6 RENAME COLUMN LOCATION2 TO LOC;

 

테이블 이름 변경

RENAME DEPT6 TO DEPT7;

 

테이블 내용 잘라내기

TRUNCATE TABLE DEPT7;

 

------------------

세션 - 클라이언트가 서버에 접속 되어 있는 상태

임시테이블 - 같은 계정으로 접속 되어도 세션이 다르면 보이지 않는 임시적으로 만든 테이블

------------------

-- 4. 참조되어지는 테이블을 CASCADE CONSTRAINTS 옵션을 통해 삭제한다. 

SQL> DROP TABLE department CASCADE CONSTRAINTS;

 

------------------

임시테이블

 

테이블 복사

 

테이블 컬럼만 가져오기

 

------------------

PL/SQL

오라클 전용 프로그램 랭귀지

선언부 DECLARE/ 실행부 BEGIN/ 예외처리부 EXCEPTION로 나뉜다

 

테스트 테이블 생성

CREATE TABLE PL_TEST
(NO NUMBER,
NAME VARCHAR2(10));

 

테스트 시퀀스 생성

CREATE SEQUENCE PL_SEQ;

 

프로시저랭귀지 SQL 실행

BEGIN
    INSERT INTO PL_TEST
    VALUES(PL_SEQ.NEXTVAL,'AAA');
END;
/

 

PLSQL을 한번 더 실행하면

---------------------------------------

 

PLSQL 테스트

test_data_eng.sql
0.03MB

 

결과값을 화면에 출력하는 기능 ON

SET SERVEROUTPUT ON;

 

 

SET SERVEROUTPUT ON;

DECLARE
    V_EMPID EMP.EMPNO%TYPE;
    V_SALARY EMP.SAL%TYPE;
BEGIN
    SELECT EMPNO, SAL INTO V_EMPID, V_SALARY
    FROM EMP
    WHERE EMPNO = 7369;
    
    DBMS_OUTPUT.PUT_LINE(V_EMPID|| ' == ' ||V_SALARY);
END;
/

 

 

DECLARE
    V_EMPID EMP.EMPNO%TYPE;
    V_SALARY EMP.SAL%TYPE;
BEGIN
    SELECT EMPNO, SAL INTO V_EMPID, V_SALARY
    FROM EMP
    WHERE EMPNO = &EMPNO;
    
    DBMS_OUTPUT.PUT_LINE(V_EMPID|| ' == ' ||V_SALARY);
END;
/

 

 

CREATE TABLE PL_TEST2
(NO NUMBER,
NAME VARCHAR2(10),
ADDR VARCHAR2(10));

SET VERIFY OFF -- 유효성체크 출력여부
DECLARE
    V_NO NUMBER := '&NO';
    V_NAME VARCHAR2(10) := '&NAME';
    V_ADDR VARCHAR2(10) := '&ADDR';
BEGIN
    INSERT INTO PL_TEST2
    VALUES(V_NO, V_NAME, V_ADDR);
END;
/

------------------------------

 

 

레코드 타입 record

테이블 타입

바인드 변수

 

 

'Database > OracleSQL' 카테고리의 다른 글

데이터베이스의 내용을 Json으로 변경하여 웹에 띄우기  (0) 2020.05.14
200512  (0) 2020.05.12
200506  (0) 2020.05.06
데이터베이스 ALL, SOME  (0) 2020.05.06
데이터베이스 무결성  (0) 2020.04.27

카드레이아웃의 기본은 아래 블로그에서 이해하자

https://m.blog.naver.com/PostView.nhn?blogId=shimchan2&logNo=70108791279&proxyReferer=https:%2F%2Fwww.google.com%2F

 

자바 GUI - CardLayout

import java.awt.*; import java.awt.event.*; public class CardLayoutTest {  /** * 카드레이아웃 이용...

blog.naver.com

 

이 글에서는 카드레이아웃과 그것을 사용한 리스너 컨트롤에 대해서 설명할 것이다.

 

기본 프레임 제작은 windowBuider를 사용하였으니 참고하자.

모든 파일은 따로 만들었다.

아래에 파일이 있으니 참고로 사용하자.

listenAdapter.java
0.00MB
CookieRun.java
0.00MB
IntroPanel.java
0.00MB
LoginPanel.java
0.00MB

 

 

리스너 어댑터 파일

리스너 어댑터는 필요없는 리스너들을 쓰지 않을 수 있도록 하는 중간 다리 역할이다.

키리스너 마우스리스너 액션리스너 인터페이스를 받아서 어댑터를 만들었다.

 

인트로 패널 파일

다른 파일로 만든 인트로 클래스이다.

이미지를 그리는 기능 밖에 없다.

 

로그인패널 파일

더보기를 눌러 로그인패널 코드 확인

더보기
package Test5;

import java.awt.AlphaComposite;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class LoginPanel extends JPanel {
	
	JLabel idLabel;
	JLabel pwLabel;
	
	JTextField idField;
	JPasswordField pwField;
	
	JButton loginBtn;
	JButton signBtn;
	
	ImageIcon loginIc = new ImageIcon("img/out/intro.png");
	private AlphaComposite alphaComposite;
	
	public LoginPanel(Object o) {
		idLabel = new JLabel("ID : ");
		Font f1 = new Font("Arial", Font.PLAIN, 20);
		idLabel.setFont(f1);
		idLabel.setBounds(550, 50, 100, 20);
		add(idLabel);
		
		pwLabel = new JLabel("PW : ");
		pwLabel.setFont(f1);
		pwLabel.setBounds(550, 80, 100, 20);
		add(pwLabel);
		
		idField = new JTextField();
		idField.setBounds(650, 50, 110, 20);
		add(idField);
		
		pwField = new JPasswordField();
		pwField.setBounds(650, 80, 110, 20);
		add(pwField);
		
		loginBtn = new JButton("login");
		loginBtn.setName("loginBtn");
		loginBtn.addMouseListener((MouseListener)o);
		loginBtn.setBounds(660, 110, 100, 20);
		add(loginBtn);
		
		signBtn = new JButton("sign");
		signBtn.setName("signBtn");
		signBtn.setBounds(550, 110, 100, 20);
		signBtn.addMouseListener((MouseListener)o);
		add(signBtn);
	}
	
	public String getId(){
		return idField.getText();
	}
	
	public String getPw(){
		return pwField.getText();
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D)g;
		
		alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)100/255);
		g2.setComposite(alphaComposite);
		
		g.drawImage(loginIc.getImage(), -60, 0,/* this.getWidth(), this.getHeight(),*/ null);
		
		alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)255/255);
		g2.setComposite(alphaComposite);
		
	}
}

 

코드가 길어보이지만 크게 어려울 것은 없다.

라벨 2개

텍스트필드, 패스워드필드 하나씩

버튼 2개 선언

생성자에서 각 컴포넌트를 생성하고 위치를 정해주고 추가한다.

생성자가 Object 매개변수를 받는데,

메인 클래스가 리스너 역할을 하기 때문에 메인에서 자기자신을 로그인패널에 넣어주면

리스너를 이용할 수 있기 때문이다.

지금 이해가 바로 안되더라도 계속 진행해보자.

아이디와 패스워드를 리턴하는 메서드를 생성

 

 

메인 클래스 파일

메인클래스는 맨위에서 만들어둔 listenAdapter를 상속받는다.

그리고 전역공간에 각종 패널들의 레퍼런스만 선언해두고,

카드레이아웃 레퍼런스도 선언해두자.

 

 

초기화 메서드

초기화 메서드에서 카드레이아웃 레퍼런스(cl)에  카드레이아웃 객체를 연결하고

프레임의 레이아웃을 카드로 변경한다.

로그인패널에서 Object를 매개변수로 받았다는 점을 기억할 것이다.

위 사진을보면 LoginPanel생성자 뒤에 this를 넘겨준다.

this는 이 메인클래스 자체를 의미하며, 메인클래스는 리스너를 상속받고 있으니 리스너 역할을 하게된다.

인트로패널에 마우스리스너를 넣어주자. 마찬가지로 this를 넘겨준다.

카드레이아웃은 컨텐트페인에 여러개의 패널을 추가할 수 있다.

만들어둔 패널들을 모두 추가하자. 추가할 시 이름을 정해줘야한다.

마지막으로 리스너 내용들이다.

메인 클래스는 리스너를 상속받았기때문에 클래스 내부에 리스너들을 넣을 수 있다.

인트로 패널에서 사용될 기능이다.

화면을 누르면 로그인페이지로 넘어가도록 하였다.

 

1. null
2. ""
3. ''
4. 0

-------------

오라클에서는 " " 과 ' ' 둘다 허용한다.

String은 특수함

----------

오라클에서는 값을 담아주지 않으면 null이 들어간다. (C나 자바에서는 쓰레기 값 등이 들어간다)

------------

null은 값이 아니기 때문에 +100 등을 해줘도 null이 된다.

----------

count는 값이 없어도 0으로 나온다?

-----------

NVL은 자주씀

----------

스칼라 - 값 (대각선으로 500미터 앞) 

벡터 - x y z 값

----------

인라인뷰 (FROM 부속쿼리)는 무조건 비상관쿼리다

스칼라부속질의 - 단일값을 반환한다. 상관 비상관 둘다가능

where질의 - 상관 비상관 구분

-----------

성능평가는 직접해야한다.

-----------

view를 만드는 이유

- 공개할 정보 선정 (컬럼, 튜플 등 개수 조정)
- 수정이 용이 (뷰를 수정하면 테이블도 수정되기 때문)
- select등 검색속도 향상 (100만개의 테이블을 10만개씩 나누어서 검색하는 등)

----------

뷰를 수정할 때에는 alter 가 아니라 replace를 사용해야한다

뷰를 생성 (또는 이미 있다면 수정)

-------------------------------

index

정렬된 데이터 중에 눈에 보이지 않는 번호를 index라고 이해하자 

-------------

복합인덱스를 사용할경우

처음에 많이 걸러줄 수 있는 조건을 거는 것이 좋다

---------------

index 주의사항

index는 select이외의 insert update delete가 느리다 

delete시 index데이터는 지워지지 않는다

update시 delete + lnsert 현상이 발생한다

예를들어 "가나라" 가있는데 "다" 가 들어가면 " 가나다라"순으로 정렬해야하니 정렬하는 시간이 걸린다는 뜻

 

index rebuild 는

insert나 delete등으로 순서가 빈 index들을 재정렬 해주는 것이다.

(서버 점검시에 수동으로 하는 경우가 많다.)

 

order by는 느리고 아래 방식으로 index로 정렬하면 빠르다

(역정렬도 체크해보자)

 

http://www.gurubee.net/lecture/2927

 

인덱스의 핵심인 ROWID 이해

인덱스의 핵심 중 하나는 ROWID다. ROWID는 데이터베이스 내 데이터 공유의 주소로, 이를 통해 데이터에 접근할 수 있어 DBA라면 반드시 이해해야..

www.gurubee.net

 

 

 

 

 

 

'Database > OracleSQL' 카테고리의 다른 글

200512  (0) 2020.05.12
200507  (0) 2020.05.07
데이터베이스 ALL, SOME  (0) 2020.05.06
데이터베이스 무결성  (0) 2020.04.27
데이터 베이스 모델링  (0) 2020.04.24
SELECT
    orderid, saleprice
FROM orders
WHERE saleprice > ALL(SELECT saleprice
                        FROM orders
                        WHERE custid='3');

ALL은 부속질의에 나온 값 모든 것들을 말한다

위의 코드에서는 모든 값들보다 큰 값을 걸러내는 것( and와 비슷 )

 

SELECT
    orderid, saleprice
FROM orders
WHERE saleprice > SOME(SELECT saleprice
                        FROM orders
                        WHERE custid='3');

 

SOME은 부속질의에 나온 값 중 하나의 조건만 만족해도 되는 것을 말한다(or과 비슷하다)

 

 

 

 

 

 

 

 

'Database > OracleSQL' 카테고리의 다른 글

200507  (0) 2020.05.07
200506  (0) 2020.05.06
데이터베이스 무결성  (0) 2020.04.27
데이터 베이스 모델링  (0) 2020.04.24
자바 데이터베이스에서 자료 가져오기  (0) 2020.04.22

 

더보기

쿠키런 프로젝트 시리즈
1.준비
https://ondolroom.tistory.com/297
2.전역공간
https://ondolroom.tistory.com/298
3.JPanel생성자
https://ondolroom.tistory.com/299
4.mapMove메서드
https://ondolroom.tistory.com/300
5.hit메서드
https://ondolroom.tistory.com/301
6.fall메서드
https://ondolroom.tistory.com/302
7.jump메서드
https://ondolroom.tistory.com/303
8.paintComponent 및 결과
https://ondolroom.tistory.com/304

이제 화면에 그림만 그리면 게임이 작동이 된다.

지금 사용할 방식은 화면에 바로그리는게 아닌 미리 그려놓고 출력하는

더블버퍼링 방식이다.

https://ondolroom.tistory.com/299

 

자바 스윙 쿠키런 만들기 MyPanel 생성자 수정 (프로젝트 진행)

https://ondolroom.tistory.com/298 자바 스윙 쿠키런 만들기 전역 변수 선언하기 (프로젝트 진행) 들어가기 전에... 아래 내용을 숙지하고 시작하자 https://ondolroom.tistory.com/279 자바 WindowBuilder 설치..

ondolroom.tistory.com

전역공간에서 미리 만들어둔 변수

이것들을 이제 이용하게 된다.

 

더보기를 눌러 전체코드 확인

더보기
		@Override
		protected void paintComponent(Graphics g) {

			
			// 더블버퍼는 그림을 미리그려놓고 화면에 출력한다.
			
			// 더블버퍼 관련
			if (buffg == null) {
				buffImage = createImage(this.getWidth(), this.getHeight());
				if (buffImage == null) {
					System.out.println("더블 버퍼링용 오프 스크린 생성 실패");
				} else {
					buffg = buffImage.getGraphics();
				}
			}
			
			//투명도 관련
			Graphics2D g2 = (Graphics2D)buffg; 
			
			super.paintComponent(buffg); // 이전 이미지를 지운다.
			
			// 배경이미지를 그린다
			buffg.drawImage(b11.getImage(), b11.getX(), 0, null);
			buffg.drawImage(b12.getImage(), b12.getX(), 0, null);

			// 발판을 그린다
			for (int i = 0; i < fieldList.size(); i++) {

				Field tempFoot = fieldList.get(i);

				// 사양을 덜 잡아먹게 하기위한 조치
				if (tempFoot.getX() > -90 && tempFoot.getX() < 810) { // x값이 -90~810인 객체들만 그린다.
					
					buffg.drawImage(
						tempFoot.getImage(), 
						tempFoot.getX(), 
						tempFoot.getY(), 
						tempFoot.getWidth(),
						tempFoot.getHeight(), 
						null);
				}

			}
			
			// 젤리를 그린다
			for (int i = 0; i < jellyList.size(); i++) {

				Jelly tempJelly = jellyList.get(i);

				if (tempJelly.getX() > -90 && tempJelly.getX() < 810) {
					
					buffg.drawImage(
						tempJelly.getImage(), 
						tempJelly.getX(), 
						tempJelly.getY(), 
						tempJelly.getWidth(),
						tempJelly.getHeight(), 
						null);
				}
			}
			
			// 장애물을 그린다
			for (int i = 0; i < tacleList.size(); i++) {

				Tacle tempTacle = tacleList.get(i);

				if (tempTacle.getX() > -90 && tempTacle.getX() < 810) {
					
					buffg.drawImage(
						tempTacle.getImage(), 
						tempTacle.getX(), 
						tempTacle.getY(), 
						tempTacle.getWidth(),
						tempTacle.getHeight(), 
						null);
				}
			}
			
			if(c1.isInvincible()) {
				// 쿠키의 alpha값을 받아온다
				alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)c1.getAlpha()/255);
				g2.setComposite(alphaComposite);
				
				// 쿠키를 그린다
				buffg.drawImage(c1.getImage(), c1.getX(), c1.getY(), c1.getWidth(), c1.getHeight(), null);
				
				// alpha값을 되돌린다
				alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)255/255);
				g2.setComposite(alphaComposite);
			} else {
				// 쿠키를 그린다
				buffg.drawImage(c1.getImage(), c1.getX(), c1.getY(), c1.getWidth(), c1.getHeight(), null);
			}
		    
		    buffg.setColor(Color.BLACK);
		    buffg.drawString(Integer.toString(resultScore), 700, 40); // 점수
		    
		    buffg.setColor(Color.GREEN);
		    buffg.fillRect(50, 40, c1.getHealth()/2, 30); // 체력게이지
		    
		    if(escKeyOn) { // esc키를 누를경우 화면을 흐리게 만든다
		    	
		    	// alpha값을 반투명하게 만든다
				alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)100/255);
			    g2.setComposite(alphaComposite);
			    
			    buffg.setColor(Color.BLACK);
			    
		    	buffg.fillRect(0, 0, 850, 550);
		    	
				// alpha값을 되돌린다
				alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)255/255);
			    g2.setComposite(alphaComposite);
		    }
			
			// 버퍼이미지를 화면에 출력한다
			g.drawImage(buffImage, 0, 0, this);
			
		}

 

설명

 

더블버퍼 객체 생성

buffImage는 메모리에서 미리 그려둘 이미지이고,
buffg는 그 이미지를 그리는 역할이라고 생각 하면된다.

buffg가 없다면 이미지를 생성하고 buffg도 buffgImage에서 그릴 권한을 받아온다.

 

투명도 관련이라고 적어 놓았지만, 기능이 다양할 것이다. 여기서는 투명도에서만 사용할 예정.

 

이전에 화면에 그렸던 이미지를 지운다, 지우지 않는다면 이전화면이 겹쳐서 출력될 수 있다.

 

배경이미지를 그린다.

 

발판을 그리는데

발판의 x값을 확인하여 화면에 가까이 있는 녀석들만 그려준다.
(예를들어 맵이 엄청 긴데 안보이는 맵까지 다 그리게 만든다면 엄청 느려질 것이다.
다만 자바에서 이것을 자동으로 없애주는지 모르는 상황이라 직접 제한하였다.)

 

같은 방식으로 젤리와 장애물을 그린다.

 

쿠키를 그리는데 쿠키가 무적일 경우에는 투명하게 깜빡여야 하기 때문에 조건을 추가한다.

 

점수와 체력게이지를 넣는다.

점수는 drawString기능을 사용해보았다. (더좋은 기능이 있다면 변경 예정)

 

esc메뉴를 누르면 화면이 흐려지는 효과를 내기 위한 코드이다.

 

마지막으로 buffImage에 그린 이미지를 g로 패널에 그린다.

 

결과

이런 허접한 그림을 사용한 이유는 규격화 때문이다.

캐릭터나 장애물들을 새로 추가하여도 항상 사이즈를 같게 하며, 여러명이서 작업시 기준이 될 수 있다.

간단한 이미지로 구현한 뒤 이미지만 바꾸면 된다. 

 

 

영상

이미지를 바꾸고 카드레이아웃을 이용하여 인트로 / 선택 / 게임 / 결과 화면을 구현

더보기

쿠키런 프로젝트 시리즈
1.준비
https://ondolroom.tistory.com/297
2.전역공간
https://ondolroom.tistory.com/298
3.JPanel생성자
https://ondolroom.tistory.com/299
4.mapMove메서드
https://ondolroom.tistory.com/300
5.hit메서드
https://ondolroom.tistory.com/301
6.fall메서드
https://ondolroom.tistory.com/302
7.jump메서드
https://ondolroom.tistory.com/303
8.paintComponent 및 결과
https://ondolroom.tistory.com/304

 

https://ondolroom.tistory.com/299

 

자바 스윙 쿠키런 만들기 MyPanel 생성자 수정 (프로젝트 진행)

https://ondolroom.tistory.com/298 자바 스윙 쿠키런 만들기 전역 변수 선언하기 (프로젝트 진행) 들어가기 전에... 아래 내용을 숙지하고 시작하자 https://ondolroom.tistory.com/279 자바 WindowBuilder 설치..

ondolroom.tistory.com

 

지난 생성자 파트에서 점프 메서드를 넣었던 것을 기억 할 것이다.

점프 메서드는 낙하메서드와 거의 비슷하다.

다만 이것도 실제 쿠키런 게임의 작동방식과 약간 다르게 제작되었으니 참고하길 바란다.

 

더보기를 눌러 전체코드 확인

더보기
void jump() {
		new Thread(new Runnable() {

			@Override
			public void run() {

				c1.setCountJump(c1.getCountJump()+1); // 점프 횟수 증가

				int nowJump = c1.getCountJump(); // 이번점프가 점프인지 더블점프인지 저장

				c1.setJump(true); // 점프중으로 변경

				if (c1.getCountJump() == 1) { // 점프 횟수가 1이라면
					
					System.out.println("점프");
					c1.setImage(jumpIc.getImage());
					
				} else if (c1.getCountJump() == 2) { // 점프 횟수가 2라면
					
					System.out.println("더블점프");
					c1.setImage(doubleJumpIc.getImage());
					
				}

				long t1 = Util.getTime(); // 현재시간을 가져온다
				long t2;
				int set = 8; // 점프 계수 설정(0~20) 등으로 바꿔보자
				int jumpY = 1; // 1이상으로만 설정하면 된다.(while문 조건 때문)
				
				while (jumpY >= 0) { // 상승 높이가 0일때까지 반복
					
					t2 = Util.getTime() - t1; // 지금 시간에서 t1을 뺀다
					
					jumpY = set - (int) ((t2) / 40); // jumpY 를 세팅한다.
					
					c1.setY(c1.getY()-jumpY); // Y값을 변경한다.

					if (nowJump != c1.getCountJump()) { // 점프가 한번 더되면 첫번째 점프는 멈춘다.
						break;
					}
					
					if (escKeyOn) {
						long tempT1 = Util.getTime();
						long tempT2 = 0;
						while (escKeyOn) {
							try {
								Thread.sleep(10);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
						tempT2 = Util.getTime() - tempT1;
						t1 = t1 + tempT2;
					}
					
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				if (nowJump == c1.getCountJump()) { // 점프가 진짜 끝났을 때를 확인
					c1.setJump(false); // 점프상태를 false로 변경
				}

			}
		}).start();
	}

 

 

설명

 

점프 쓰레드 생성

점프 도중에도 맵은 이동하고, 우리는 더블점프를 해야 하기 때문에

새 쓰레드를 이용한다.

 

점프 횟수를 1 늘려주고

이번 쓰레드의 점프가 1회인지 2회인지 임시변수에 저장한다. (추후점프 상태를 false로 변환하기 위함)

예를들어 1회 점프 중에 한번 더 점프하여 지금점프가 break되었는데 점프 상태를 false로 바꾸게되면 문제가 발생한다.

그것을 방지하기 위해 현재 점프횟수를 기록해두는 것.

c1(캐릭터)의 점프 상태도 true로 변경하자.

그리고 이번 점프가 1회려면 점프, 2회라면 더블점프 이미지로 변경한다.

 

내용이 길어서 아래에서 나누어서 설명하겠다.

 

Util클래스에서 타임스탬프 시간을 가져온다.

t2는 바로 뒤에 쓸예정이니 선언만 해둔다.

set은 점프 계수인데 처음 점프량을 설정한다.
(예를들어 캐릭터의 높이가 8씩 증가하다가 7 6 5 4 3 2 1 0 씩 증가하게 되는데, set은 그 초기값이다.)

 

상승은 점프량이 0이 될때까지 반복하게 된다.

t2에 현재시간 - 점프가 시작된시간을 저장하고

set에 그값을 가공한뒤 빼서 jumpY를 세팅한다. (jumpY는 상승량이라고 보면된다.)

그것으로 캐릭터의 높이를 재설정해준다.

 

캐릭터가 1회점프 도중 한번더 점프를 하면 이번 점프는 멈춰야된다. (중복되면 가속상승이 되버린다.)

 

낙하 때와 마찬가지로 esc메뉴가 뜬 상태에서는 위와 같이 시간을 저장해두었다가 t1에 넣어준다.

 

while무한반복문에는 대기시간을 넣어 리소스를 안정화 시키자

이번 쓰레드의 점프가 진짜 끝났는지 확인하고 맞다면 점프상태를 false로 변경한다.

 

다음편에 계속

+ Recent posts