영상으로 대신합니다.
먼저, 내 도시를 다른 사람에게 공유하는 방법
다른 사람 도시 받아 불러오는 방법
HJOW의 신버전 블로그입니다. 이 블로그는 제 관심사에 해당하는 기사, 동영상 등을 퍼오거나, 작성하는 곳으로, 마음껏 퍼가셔도 됩니다.
영상으로 대신합니다.
먼저, 내 도시를 다른 사람에게 공유하는 방법
다른 사람 도시 받아 불러오는 방법
사진과 같이 ~
먼저, 폴더 창을 엽니다. 아무 폴더나 상관없음.
폴더창 상단에 보면 주소창이 있는데,
빈 곳을 클릭하면 키보드로 입력할 수 있게 바뀜.
샘플로 내 최초 100만 인구 달성 도시를 공유한다.
Paradox Mods 로 도시 공유가 가능해졌기 때문에, 그 링크를 먼저 남긴다.
https://mods.paradoxplaza.com/mods/87348/Windows
파일로 받고 싶어하시는 분들을 위해...
원드라이브 링크 : Gilbert_20241027_0017.zip
대뜸 예제 첨부
일단 아래와 같은 클래스를 만들어 둔다.
import java.io.File;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
/** Class to play wav file */
public class SoundClip implements Serializable
{
private static final long serialVersionUID = -4189707921602251694L;
protected URL url;
protected double volume = 100.0;
protected transient boolean flagStop = false;
/** Create instance with URL to get wav file */
public SoundClip(URL url)
{
this.url = url;
}
/** Create instance with wav file */
public SoundClip(File f) throws MalformedURLException
{
this(f.toURI().toURL());
}
/** Play wav sound now */
public void start()
{
if(url == null) return;
flagStop = false;
AudioInputStream inp1 = null;
AudioInputStream inp2 = null;
SourceDataLine line = null;
try
{
byte[] buffer = new byte[4096];
int reads;
// Load wav from URL
inp1 = AudioSystem.getAudioInputStream(url);
if(flagStop) return; // Return when stop() method called
// Detect audio format of wav file and get converted input stream
AudioFormat formatBase = inp1.getFormat();
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, formatBase.getSampleRate(), 16, formatBase.getChannels(), formatBase.getChannels() * 2, formatBase.getSampleRate(), false);
inp2 = AudioSystem.getAudioInputStream(format, inp1);
if(flagStop) return; // Return when stop() method called
// Create SourceDataLine to play wav
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
Mixer mixer = AudioSystem.getMixer(null);
line = (SourceDataLine) mixer.getLine(info);
if(flagStop) return; // Return when stop() method called
// Open SourceDataLine
line.open(format);
// This must be in here (after line opened !)
FloatControl ctrl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
ctrl.setValue((float) (20.0f * Math.log10(volume / 100.0)));
// Play Start
line.start();
while(! flagStop)
{
reads = inp2.read(buffer, 0, buffer.length);
if(reads < 0) break; // Return when stop() method called
line.write(buffer, 0, reads);
}
// END
line.drain();
line.stop();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
try { line.close(); } catch(Exception ex) {}
try { inp2.close(); } catch(Exception ex) {}
try { inp1.close(); } catch(Exception ex) {}
flagStop = false;
}
}
/** Play wav sound now */
public void play()
{
start();
}
/** Stop playing */
public void stop()
{
flagStop = true;
}
/** Get volume (0 ~ 100) default 100 */
public double getVolume()
{
return volume;
}
/** Set volume (0 ~ 100) default 100 */
public void setVolume(double volume)
{
this.volume = volume;
if(this.volume < 0) this.volume = 0;
}
/** Get URL of wav file */
public URL getUrl() {
return url;
}
/** Set wav file */
public void setUrl(URL url) {
this.url = url;
}
}
이제 이걸 써먹으면 된다.
문제가 있는데, 사운드를 재생하는 동안 쓰레드를 독차지하고 있게 된다.
즉, 재생하는 동안 그 아래 코드들은 사운드 재생이 끝날 때까지 실행되지 않는다.
그래서 별도 쓰레드를 많이 만들어 두어서 재생 작업을 쓰레드에서 해야 된다.
기존 Beton Brutal 의 DLC Beton Bath 는 너무 난이도가 어려웠습니다.
Beton Brutal
https://store.steampowered.com/app/2330500/BETON_BRUTAL/